summaryrefslogtreecommitdiff
path: root/gnuradio-core/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'gnuradio-core/src/lib')
-rw-r--r--gnuradio-core/src/lib/Makefile.am62
-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.S95
-rw-r--r--gnuradio-core/src/lib/filter/3dnow_float_dotprod_simple.S102
-rw-r--r--gnuradio-core/src/lib/filter/Makefile.am306
-rw-r--r--gnuradio-core/src/lib/filter/Makefile.gen111
-rw-r--r--gnuradio-core/src/lib/filter/README28
-rw-r--r--gnuradio-core/src/lib/filter/assembly.h58
-rw-r--r--gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow.S216
-rw-r--r--gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow64.S213
-rw-r--r--gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext.S191
-rw-r--r--gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext64.S188
-rw-r--r--gnuradio-core/src/lib/filter/ccomplex_dotprod_generic.cc59
-rw-r--r--gnuradio-core/src/lib/filter/ccomplex_dotprod_generic.h32
-rw-r--r--gnuradio-core/src/lib/filter/ccomplex_dotprod_sse.S194
-rw-r--r--gnuradio-core/src/lib/filter/ccomplex_dotprod_sse64.S191
-rw-r--r--gnuradio-core/src/lib/filter/ccomplex_dotprod_x86.h46
-rw-r--r--gnuradio-core/src/lib/filter/complex_dotprod_3dnow.S188
-rw-r--r--gnuradio-core/src/lib/filter/complex_dotprod_3dnow64.S183
-rw-r--r--gnuradio-core/src/lib/filter/complex_dotprod_3dnowext.S167
-rw-r--r--gnuradio-core/src/lib/filter/complex_dotprod_3dnowext64.S164
-rw-r--r--gnuradio-core/src/lib/filter/complex_dotprod_generic.cc55
-rw-r--r--gnuradio-core/src/lib/filter/complex_dotprod_generic.h32
-rw-r--r--gnuradio-core/src/lib/filter/complex_dotprod_sse.S202
-rw-r--r--gnuradio-core/src/lib/filter/complex_dotprod_sse64.S198
-rw-r--r--gnuradio-core/src/lib/filter/complex_dotprod_x86.h46
-rw-r--r--gnuradio-core/src/lib/filter/cpuid_x86.S56
-rw-r--r--gnuradio-core/src/lib/filter/cpuid_x86_64.S50
-rw-r--r--gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow.S172
-rw-r--r--gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow64.S166
-rw-r--r--gnuradio-core/src/lib/filter/fcomplex_dotprod_sse.S184
-rw-r--r--gnuradio-core/src/lib/filter/fcomplex_dotprod_sse64.S179
-rw-r--r--gnuradio-core/src/lib/filter/fcomplex_dotprod_x86.h42
-rw-r--r--gnuradio-core/src/lib/filter/filter.i45
-rw-r--r--gnuradio-core/src/lib/filter/float_dotprod_3dnow.S148
-rw-r--r--gnuradio-core/src/lib/filter/float_dotprod_3dnow64.S145
-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.S167
-rw-r--r--gnuradio-core/src/lib/filter/float_dotprod_sse64.S161
-rw-r--r--gnuradio-core/src/lib/filter/float_dotprod_x86.h44
-rwxr-xr-xgnuradio-core/src/lib/filter/generate_all.py46
-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.py127
-rwxr-xr-xgnuradio-core/src/lib/filter/generate_gr_fir_sysconfig_generic.py182
-rwxr-xr-xgnuradio-core/src/lib/filter/generate_gr_fir_util.py185
-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
-rw-r--r--gnuradio-core/src/lib/filter/generate_utils.py31
-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.h57
-rw-r--r--gnuradio-core/src/lib/filter/gr_adaptive_fir_ccf.i30
-rw-r--r--gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.cc41
-rw-r--r--gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.h62
-rw-r--r--gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.i35
-rw-r--r--gnuradio-core/src/lib/filter/gr_cpu.cc107
-rw-r--r--gnuradio-core/src/lib/filter/gr_cpu.h34
-rw-r--r--gnuradio-core/src/lib/filter/gr_fft_filter_ccc.cc210
-rw-r--r--gnuradio-core/src/lib/filter/gr_fft_filter_ccc.h77
-rw-r--r--gnuradio-core/src/lib/filter/gr_fft_filter_ccc.i39
-rw-r--r--gnuradio-core/src/lib/filter/gr_fft_filter_fff.cc211
-rw-r--r--gnuradio-core/src/lib/filter/gr_fft_filter_fff.h76
-rw-r--r--gnuradio-core/src/lib/filter/gr_fft_filter_fff.i39
-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.h72
-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.t123
-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.t77
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_ccc_simd.cc139
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_ccc_simd.h63
-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.h55
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_ccf_simd.cc138
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_ccf_simd.h64
-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.h48
-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.h64
-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.h48
-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.h62
-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.h48
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_filter_XXX.cc.t88
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_filter_XXX.h.t67
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_filter_XXX.i.t41
-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.h62
-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.h48
-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.h64
-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.h58
-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.h46
-rw-r--r--gnuradio-core/src/lib/filter/gr_fractional_interpolator.cc97
-rw-r--r--gnuradio-core/src/lib/filter/gr_fractional_interpolator.h62
-rw-r--r--gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.cc.t122
-rw-r--r--gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.h.t100
-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.cc60
-rw-r--r--gnuradio-core/src/lib/filter/gr_goertzel_fc.h55
-rw-r--r--gnuradio-core/src/lib/filter/gr_goertzel_fc.i31
-rw-r--r--gnuradio-core/src/lib/filter/gr_hilbert_fc.cc67
-rw-r--r--gnuradio-core/src/lib/filter/gr_hilbert_fc.h68
-rw-r--r--gnuradio-core/src/lib/filter/gr_hilbert_fc.i34
-rw-r--r--gnuradio-core/src/lib/filter/gr_iir_filter_ffd.cc88
-rw-r--r--gnuradio-core/src/lib/filter/gr_iir_filter_ffd.h89
-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.t69
-rw-r--r--gnuradio-core/src/lib/filter/gr_interp_fir_filter_XXX.i.t41
-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.t87
-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.h50
-rw-r--r--gnuradio-core/src/lib/filter/gr_sincos.c81
-rw-r--r--gnuradio-core/src/lib/filter/gr_sincos.h39
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_pole_avg.h110
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_pole_avg_filter_ff.cc81
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_pole_avg_filter_ff.h76
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_pole_avg_filter_ff.i34
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_pole_iir.h190
-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.h77
-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.h76
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_ff.i34
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_pole_rec.h110
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_pole_rec_filter_ff.cc81
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_pole_rec_filter_ff.h76
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_pole_rec_filter_ff.i34
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_zero_avg.h110
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_zero_avg_filter_ff.cc81
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_zero_avg_filter_ff.h76
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_zero_avg_filter_ff.i34
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_zero_rec.h110
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_zero_rec_filter_ff.cc81
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_zero_rec_filter_ff.h76
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_zero_rec_filter_ff.i34
-rw-r--r--gnuradio-core/src/lib/filter/gri_goertzel.cc66
-rw-r--r--gnuradio-core/src/lib/filter/gri_goertzel.h55
-rw-r--r--gnuradio-core/src/lib/filter/gri_iir.h164
-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.h65
-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.h66
-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_generic.cc32
-rw-r--r--gnuradio-core/src/lib/filter/qa_dotprod_x86.cc37
-rw-r--r--gnuradio-core/src/lib/filter/qa_filter.cc52
-rw-r--r--gnuradio-core/src/lib/filter/qa_filter.h37
-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.cc183
-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.cc183
-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.cc180
-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.cc225
-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_gri_mmse_fir_interpolator.cc62
-rw-r--r--gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator.h40
-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.S113
-rw-r--r--gnuradio-core/src/lib/filter/short_dotprod_mmx64.S101
-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_generic.cc35
-rw-r--r--gnuradio-core/src/lib/filter/sysconfig_x86.cc38
-rw-r--r--gnuradio-core/src/lib/g72x/Makefile.am27
-rw-r--r--gnuradio-core/src/lib/g72x/README94
-rw-r--r--gnuradio-core/src/lib/g72x/decode.c113
-rw-r--r--gnuradio-core/src/lib/g72x/encode.c119
-rw-r--r--gnuradio-core/src/lib/g72x/g711.c283
-rw-r--r--gnuradio-core/src/lib/g72x/g721.c173
-rw-r--r--gnuradio-core/src/lib/g72x/g723_24.c158
-rw-r--r--gnuradio-core/src/lib/g72x/g723_40.c178
-rw-r--r--gnuradio-core/src/lib/g72x/g72x.c576
-rw-r--r--gnuradio-core/src/lib/g72x/g72x.h156
-rw-r--r--gnuradio-core/src/lib/general/Makefile.am440
-rw-r--r--gnuradio-core/src/lib/general/Makefile.gen234
-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
-rwxr-xr-xgnuradio-core/src/lib/general/gen_sine_table.py77
-rw-r--r--gnuradio-core/src/lib/general/general.i203
-rw-r--r--gnuradio-core/src/lib/general/general_generated.i156
-rwxr-xr-xgnuradio-core/src/lib/general/generate_all.py33
-rwxr-xr-xgnuradio-core/src/lib/general/generate_common.py93
-rw-r--r--gnuradio-core/src/lib/general/gr_add_XX.cc.t62
-rw-r--r--gnuradio-core/src/lib/general/gr_add_XX.h.t54
-rw-r--r--gnuradio-core/src/lib/general/gr_add_XX.i.t33
-rw-r--r--gnuradio-core/src/lib/general/gr_add_const_XX.cc.t72
-rw-r--r--gnuradio-core/src/lib/general/gr_add_const_XX.h.t55
-rw-r--r--gnuradio-core/src/lib/general/gr_add_const_XX.i.t37
-rwxr-xr-xgnuradio-core/src/lib/general/gr_add_const_vXX.cc.t61
-rwxr-xr-xgnuradio-core/src/lib/general/gr_add_const_vXX.h.t55
-rwxr-xr-xgnuradio-core/src/lib/general/gr_add_const_vXX.i.t37
-rwxr-xr-xgnuradio-core/src/lib/general/gr_add_vXX.cc.t65
-rwxr-xr-xgnuradio-core/src/lib/general/gr_add_vXX.h.t54
-rwxr-xr-xgnuradio-core/src/lib/general/gr_add_vXX.i.t33
-rw-r--r--gnuradio-core/src/lib/general/gr_agc_cc.cc54
-rw-r--r--gnuradio-core/src/lib/general/gr_agc_cc.h50
-rw-r--r--gnuradio-core/src/lib/general/gr_agc_cc.i33
-rw-r--r--gnuradio-core/src/lib/general/gr_agc_ff.cc54
-rw-r--r--gnuradio-core/src/lib/general/gr_agc_ff.h50
-rw-r--r--gnuradio-core/src/lib/general/gr_agc_ff.i33
-rw-r--r--gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.cc461
-rw-r--r--gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.h89
-rw-r--r--gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.i33
-rw-r--r--gnuradio-core/src/lib/general/gr_binary_slicer_fb.cc64
-rw-r--r--gnuradio-core/src/lib/general/gr_binary_slicer_fb.h51
-rw-r--r--gnuradio-core/src/lib/general/gr_binary_slicer_fb.i33
-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.h60
-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.cc55
-rw-r--r--gnuradio-core/src/lib/general/gr_char_to_float.h51
-rw-r--r--gnuradio-core/src/lib/general/gr_char_to_float.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.h88
-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.h102
-rw-r--r--gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.i36
-rw-r--r--gnuradio-core/src/lib/general/gr_chunks_to_symbols_XX.cc.t73
-rw-r--r--gnuradio-core/src/lib/general/gr_chunks_to_symbols_XX.h.t72
-rw-r--r--gnuradio-core/src/lib/general/gr_chunks_to_symbols_XX.i.t37
-rw-r--r--gnuradio-core/src/lib/general/gr_circular_file.cc194
-rw-r--r--gnuradio-core/src/lib/general/gr_circular_file.h58
-rw-r--r--gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.cc182
-rw-r--r--gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.h105
-rw-r--r--gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.i49
-rw-r--r--gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.cc140
-rw-r--r--gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.h93
-rw-r--r--gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.i45
-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.h51
-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.cc199
-rw-r--r--gnuradio-core/src/lib/general/gr_complex_to_xxx.h137
-rw-r--r--gnuradio-core/src/lib/general/gr_complex_to_xxx.i57
-rw-r--r--gnuradio-core/src/lib/general/gr_conjugate_cc.cc71
-rw-r--r--gnuradio-core/src/lib/general/gr_conjugate_cc.h51
-rw-r--r--gnuradio-core/src/lib/general/gr_conjugate_cc.i33
-rw-r--r--gnuradio-core/src/lib/general/gr_constellation_decoder_cb.cc113
-rw-r--r--gnuradio-core/src/lib/general/gr_constellation_decoder_cb.h61
-rw-r--r--gnuradio-core/src/lib/general/gr_constellation_decoder_cb.i43
-rw-r--r--gnuradio-core/src/lib/general/gr_correlate_access_code_bb.cc129
-rw-r--r--gnuradio-core/src/lib/general/gr_correlate_access_code_bb.h85
-rw-r--r--gnuradio-core/src/lib/general/gr_correlate_access_code_bb.i60
-rw-r--r--gnuradio-core/src/lib/general/gr_costas_loop_cc.cc118
-rw-r--r--gnuradio-core/src/lib/general/gr_costas_loop_cc.h72
-rw-r--r--gnuradio-core/src/lib/general/gr_costas_loop_cc.i37
-rw-r--r--gnuradio-core/src/lib/general/gr_count_bits.cc93
-rw-r--r--gnuradio-core/src/lib/general/gr_count_bits.h31
-rw-r--r--gnuradio-core/src/lib/general/gr_crc32.cc130
-rw-r--r--gnuradio-core/src/lib/general/gr_crc32.h43
-rw-r--r--gnuradio-core/src/lib/general/gr_crc32.i27
-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.h67
-rw-r--r--gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.i39
-rw-r--r--gnuradio-core/src/lib/general/gr_dd_mpsk_sync_cc.cc195
-rw-r--r--gnuradio-core/src/lib/general/gr_dd_mpsk_sync_cc.h92
-rw-r--r--gnuradio-core/src/lib/general/gr_dd_mpsk_sync_cc.i34
-rw-r--r--gnuradio-core/src/lib/general/gr_deinterleave.cc78
-rw-r--r--gnuradio-core/src/lib/general/gr_deinterleave.h56
-rw-r--r--gnuradio-core/src/lib/general/gr_deinterleave.i30
-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.h52
-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.h53
-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.h48
-rw-r--r--gnuradio-core/src/lib/general/gr_diff_phasor_cc.i34
-rw-r--r--gnuradio-core/src/lib/general/gr_divide_XX.cc.t71
-rw-r--r--gnuradio-core/src/lib/general/gr_divide_XX.h.t54
-rw-r--r--gnuradio-core/src/lib/general/gr_divide_XX.i.t33
-rw-r--r--gnuradio-core/src/lib/general/gr_endianness.h27
-rw-r--r--gnuradio-core/src/lib/general/gr_endianness.i23
-rw-r--r--gnuradio-core/src/lib/general/gr_expj.h37
-rw-r--r--gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.cc112
-rw-r--r--gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.h90
-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.cc198
-rw-r--r--gnuradio-core/src/lib/general/gr_feval.cc86
-rw-r--r--gnuradio-core/src/lib/general/gr_feval.h116
-rw-r--r--gnuradio-core/src/lib/general/gr_feval.i69
-rw-r--r--gnuradio-core/src/lib/general/gr_fft_vcc.cc102
-rw-r--r--gnuradio-core/src/lib/general/gr_fft_vcc.h62
-rw-r--r--gnuradio-core/src/lib/general/gr_fft_vcc.i35
-rw-r--r--gnuradio-core/src/lib/general/gr_fft_vfc.cc116
-rw-r--r--gnuradio-core/src/lib/general/gr_fft_vfc.h62
-rw-r--r--gnuradio-core/src/lib/general/gr_fft_vfc.i35
-rw-r--r--gnuradio-core/src/lib/general/gr_firdes.cc584
-rw-r--r--gnuradio-core/src/lib/general/gr_firdes.h225
-rw-r--r--gnuradio-core/src/lib/general/gr_firdes.i187
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_char.cc58
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_char.h51
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_char.i30
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_complex.cc71
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_complex.h52
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_complex.i30
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_short.cc58
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_short.h51
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_short.i30
-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.h51
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_uchar.i30
-rw-r--r--gnuradio-core/src/lib/general/gr_framer_sink_1.cc175
-rw-r--r--gnuradio-core/src/lib/general/gr_framer_sink_1.h103
-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.cc70
-rw-r--r--gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h56
-rw-r--r--gnuradio-core/src/lib/general/gr_frequency_modulator_fc.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_fxpt.cc57
-rw-r--r--gnuradio-core/src/lib/general/gr_fxpt.h82
-rw-r--r--gnuradio-core/src/lib/general/gr_fxpt_nco.h151
-rw-r--r--gnuradio-core/src/lib/general/gr_fxpt_vco.h71
-rw-r--r--gnuradio-core/src/lib/general/gr_head.cc60
-rw-r--r--gnuradio-core/src/lib/general/gr_head.h54
-rw-r--r--gnuradio-core/src/lib/general/gr_head.i30
-rw-r--r--gnuradio-core/src/lib/general/gr_interleave.cc77
-rw-r--r--gnuradio-core/src/lib/general/gr_interleave.h56
-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.h51
-rw-r--r--gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.i30
-rw-r--r--gnuradio-core/src/lib/general/gr_keep_one_in_n.cc81
-rw-r--r--gnuradio-core/src/lib/general/gr_keep_one_in_n.h60
-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.h55
-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.h60
-rw-r--r--gnuradio-core/src/lib/general/gr_lfsr_32k_source_s.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_lms_dfe_cc.cc148
-rw-r--r--gnuradio-core/src/lib/general/gr_lms_dfe_cc.h64
-rw-r--r--gnuradio-core/src/lib/general/gr_lms_dfe_cc.i37
-rw-r--r--gnuradio-core/src/lib/general/gr_lms_dfe_ff.cc122
-rw-r--r--gnuradio-core/src/lib/general/gr_lms_dfe_ff.h62
-rw-r--r--gnuradio-core/src/lib/general/gr_lms_dfe_ff.i34
-rw-r--r--gnuradio-core/src/lib/general/gr_log2_const.h46
-rw-r--r--gnuradio-core/src/lib/general/gr_map_bb.cc61
-rw-r--r--gnuradio-core/src/lib/general/gr_map_bb.h51
-rw-r--r--gnuradio-core/src/lib/general/gr_map_bb.i32
-rw-r--r--gnuradio-core/src/lib/general/gr_math.cc102
-rw-r--r--gnuradio-core/src/lib/general/gr_math.h60
-rw-r--r--gnuradio-core/src/lib/general/gr_misc.cc65
-rw-r--r--gnuradio-core/src/lib/general/gr_misc.h38
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_XX.cc.t62
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_XX.h.t54
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_XX.i.t33
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_const_XX.cc.t72
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_const_XX.h.t55
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_const_XX.i.t37
-rwxr-xr-xgnuradio-core/src/lib/general/gr_multiply_const_vXX.cc.t61
-rwxr-xr-xgnuradio-core/src/lib/general/gr_multiply_const_vXX.h.t55
-rwxr-xr-xgnuradio-core/src/lib/general/gr_multiply_const_vXX.i.t37
-rwxr-xr-xgnuradio-core/src/lib/general/gr_multiply_vXX.cc.t65
-rwxr-xr-xgnuradio-core/src/lib/general/gr_multiply_vXX.h.t54
-rwxr-xr-xgnuradio-core/src/lib/general/gr_multiply_vXX.i.t33
-rw-r--r--gnuradio-core/src/lib/general/gr_mute_XX.cc.t79
-rw-r--r--gnuradio-core/src/lib/general/gr_mute_XX.h.t55
-rw-r--r--gnuradio-core/src/lib/general/gr_mute_XX.i.t37
-rw-r--r--gnuradio-core/src/lib/general/gr_nco.h197
-rw-r--r--gnuradio-core/src/lib/general/gr_nlog10_ff.cc64
-rw-r--r--gnuradio-core/src/lib/general/gr_nlog10_ff.h55
-rw-r--r--gnuradio-core/src/lib/general/gr_nlog10_ff.i33
-rw-r--r--gnuradio-core/src/lib/general/gr_noise_source_X.cc.t99
-rw-r--r--gnuradio-core/src/lib/general/gr_noise_source_X.h.t63
-rw-r--r--gnuradio-core/src/lib/general/gr_noise_source_X.i.t37
-rw-r--r--gnuradio-core/src/lib/general/gr_noise_type.h30
-rw-r--r--gnuradio-core/src/lib/general/gr_nop.cc55
-rw-r--r--gnuradio-core/src/lib/general/gr_nop.h49
-rw-r--r--gnuradio-core/src/lib/general/gr_nop.i30
-rw-r--r--gnuradio-core/src/lib/general/gr_null_sink.cc49
-rw-r--r--gnuradio-core/src/lib/general/gr_null_sink.h51
-rw-r--r--gnuradio-core/src/lib/general/gr_null_sink.i30
-rw-r--r--gnuradio-core/src/lib/general/gr_null_source.cc51
-rw-r--r--gnuradio-core/src/lib/general/gr_null_source.h49
-rw-r--r--gnuradio-core/src/lib/general/gr_null_source.i30
-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.h62
-rw-r--r--gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.i34
-rw-r--r--gnuradio-core/src/lib/general/gr_packed_to_unpacked_XX.cc.t133
-rw-r--r--gnuradio-core/src/lib/general/gr_packed_to_unpacked_XX.h.t84
-rw-r--r--gnuradio-core/src/lib/general/gr_packed_to_unpacked_XX.i.t33
-rw-r--r--gnuradio-core/src/lib/general/gr_packet_sink.cc206
-rw-r--r--gnuradio-core/src/lib/general/gr_packet_sink.h111
-rw-r--r--gnuradio-core/src/lib/general/gr_packet_sink.i41
-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.h55
-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.cc117
-rw-r--r--gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.h70
-rw-r--r--gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.i38
-rw-r--r--gnuradio-core/src/lib/general/gr_pll_freqdet_cf.cc94
-rw-r--r--gnuradio-core/src/lib/general/gr_pll_freqdet_cf.h64
-rw-r--r--gnuradio-core/src/lib/general/gr_pll_freqdet_cf.i32
-rw-r--r--gnuradio-core/src/lib/general/gr_pll_refout_cc.cc97
-rw-r--r--gnuradio-core/src/lib/general/gr_pll_refout_cc.h66
-rw-r--r--gnuradio-core/src/lib/general/gr_pll_refout_cc.i32
-rw-r--r--gnuradio-core/src/lib/general/gr_prefix.cc.in29
-rw-r--r--gnuradio-core/src/lib/general/gr_prefix.h33
-rw-r--r--gnuradio-core/src/lib/general/gr_prefix.i5
-rw-r--r--gnuradio-core/src/lib/general/gr_prefs.cc88
-rw-r--r--gnuradio-core/src/lib/general/gr_prefs.h82
-rw-r--r--gnuradio-core/src/lib/general/gr_prefs.i72
-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.h74
-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_f.cc84
-rw-r--r--gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.h74
-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_signal_f.cc60
-rw-r--r--gnuradio-core/src/lib/general/gr_probe_signal_f.h57
-rw-r--r--gnuradio-core/src/lib/general/gr_probe_signal_f.i32
-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.h62
-rw-r--r--gnuradio-core/src/lib/general/gr_pwr_squelch_cc.i40
-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.h62
-rw-r--r--gnuradio-core/src/lib/general/gr_pwr_squelch_ff.i40
-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.h53
-rw-r--r--gnuradio-core/src/lib/general/gr_quadrature_demod_cf.i30
-rw-r--r--gnuradio-core/src/lib/general/gr_random.cc180
-rw-r--r--gnuradio-core/src/lib/general/gr_random.h63
-rw-r--r--gnuradio-core/src/lib/general/gr_remez.cc1031
-rw-r--r--gnuradio-core/src/lib/general/gr_remez.h63
-rw-r--r--gnuradio-core/src/lib/general/gr_remez.i32
-rw-r--r--gnuradio-core/src/lib/general/gr_reverse.cc60
-rw-r--r--gnuradio-core/src/lib/general/gr_reverse.h33
-rw-r--r--gnuradio-core/src/lib/general/gr_rms_cf.cc71
-rw-r--r--gnuradio-core/src/lib/general/gr_rms_cf.h59
-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.h59
-rw-r--r--gnuradio-core/src/lib/general/gr_rms_ff.i33
-rw-r--r--gnuradio-core/src/lib/general/gr_short_to_float.cc58
-rw-r--r--gnuradio-core/src/lib/general/gr_short_to_float.h51
-rw-r--r--gnuradio-core/src/lib/general/gr_short_to_float.i30
-rw-r--r--gnuradio-core/src/lib/general/gr_sig_source_X.cc.t149
-rw-r--r--gnuradio-core/src/lib/general/gr_sig_source_X.h.t81
-rw-r--r--gnuradio-core/src/lib/general/gr_sig_source_X.i.t52
-rw-r--r--gnuradio-core/src/lib/general/gr_sig_source_waveform.h29
-rw-r--r--gnuradio-core/src/lib/general/gr_simple_correlator.cc230
-rw-r--r--gnuradio-core/src/lib/general/gr_simple_correlator.h109
-rw-r--r--gnuradio-core/src/lib/general/gr_simple_correlator.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_simple_framer.cc100
-rw-r--r--gnuradio-core/src/lib/general/gr_simple_framer.h58
-rw-r--r--gnuradio-core/src/lib/general/gr_simple_framer.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_simple_framer_sync.h49
-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.h65
-rw-r--r--gnuradio-core/src/lib/general/gr_simple_squelch_cc.i37
-rw-r--r--gnuradio-core/src/lib/general/gr_skiphead.cc70
-rw-r--r--gnuradio-core/src/lib/general/gr_skiphead.h54
-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.h58
-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.h58
-rw-r--r--gnuradio-core/src/lib/general/gr_squelch_base_ff.i40
-rw-r--r--gnuradio-core/src/lib/general/gr_stream_to_streams.cc65
-rw-r--r--gnuradio-core/src/lib/general/gr_stream_to_streams.h55
-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.cc57
-rw-r--r--gnuradio-core/src/lib/general/gr_stream_to_vector.h54
-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.cc67
-rw-r--r--gnuradio-core/src/lib/general/gr_streams_to_stream.h55
-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.cc63
-rw-r--r--gnuradio-core/src/lib/general/gr_streams_to_vector.h53
-rw-r--r--gnuradio-core/src/lib/general/gr_streams_to_vector.i34
-rw-r--r--gnuradio-core/src/lib/general/gr_sub_XX.cc.t70
-rw-r--r--gnuradio-core/src/lib/general/gr_sub_XX.h.t54
-rw-r--r--gnuradio-core/src/lib/general/gr_sub_XX.i.t33
-rw-r--r--gnuradio-core/src/lib/general/gr_sync_block.cc68
-rw-r--r--gnuradio-core/src/lib/general/gr_sync_block.h65
-rw-r--r--gnuradio-core/src/lib/general/gr_sync_block.i29
-rw-r--r--gnuradio-core/src/lib/general/gr_sync_decimator.cc69
-rw-r--r--gnuradio-core/src/lib/general/gr_sync_decimator.h68
-rw-r--r--gnuradio-core/src/lib/general/gr_sync_decimator.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_sync_interpolator.cc70
-rw-r--r--gnuradio-core/src/lib/general/gr_sync_interpolator.h68
-rw-r--r--gnuradio-core/src/lib/general/gr_sync_interpolator.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_test.cc176
-rw-r--r--gnuradio-core/src/lib/general/gr_test.h199
-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.h58
-rw-r--r--gnuradio-core/src/lib/general/gr_threshold_ff.i39
-rw-r--r--gnuradio-core/src/lib/general/gr_throttle.cc109
-rw-r--r--gnuradio-core/src/lib/general/gr_throttle.h63
-rw-r--r--gnuradio-core/src/lib/general/gr_throttle.i30
-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.h51
-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.h54
-rw-r--r--gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.i34
-rw-r--r--gnuradio-core/src/lib/general/gr_unpacked_to_packed_XX.cc.t125
-rw-r--r--gnuradio-core/src/lib/general/gr_unpacked_to_packed_XX.h.t81
-rw-r--r--gnuradio-core/src/lib/general/gr_unpacked_to_packed_XX.i.t33
-rw-r--r--gnuradio-core/src/lib/general/gr_vco.h93
-rw-r--r--gnuradio-core/src/lib/general/gr_vco_f.cc58
-rw-r--r--gnuradio-core/src/lib/general/gr_vco_f.h72
-rw-r--r--gnuradio-core/src/lib/general/gr_vco_f.i38
-rw-r--r--gnuradio-core/src/lib/general/gr_vector_sink_X.cc.t63
-rw-r--r--gnuradio-core/src/lib/general/gr_vector_sink_X.h.t55
-rw-r--r--gnuradio-core/src/lib/general/gr_vector_sink_X.i.t37
-rw-r--r--gnuradio-core/src/lib/general/gr_vector_source_X.cc.t85
-rw-r--r--gnuradio-core/src/lib/general/gr_vector_source_X.h.t57
-rw-r--r--gnuradio-core/src/lib/general/gr_vector_source_X.i.t33
-rw-r--r--gnuradio-core/src/lib/general/gr_vector_to_stream.cc57
-rw-r--r--gnuradio-core/src/lib/general/gr_vector_to_stream.h53
-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.cc63
-rw-r--r--gnuradio-core/src/lib/general/gr_vector_to_streams.h53
-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_agc.h70
-rw-r--r--gnuradio-core/src/lib/general/gri_agc.i36
-rw-r--r--gnuradio-core/src/lib/general/gri_agc_cc.h71
-rw-r--r--gnuradio-core/src/lib/general/gri_agc_cc.i40
-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.h32
-rw-r--r--gnuradio-core/src/lib/general/gri_debugger_hook.cc29
-rw-r--r--gnuradio-core/src/lib/general/gri_debugger_hook.h28
-rw-r--r--gnuradio-core/src/lib/general/gri_fft.cc229
-rw-r--r--gnuradio-core/src/lib/general/gri_fft.h122
-rw-r--r--gnuradio-core/src/lib/general/gri_float_to_char.cc42
-rw-r--r--gnuradio-core/src/lib/general/gri_float_to_char.h32
-rw-r--r--gnuradio-core/src/lib/general/gri_float_to_short.cc42
-rw-r--r--gnuradio-core/src/lib/general/gri_float_to_short.h32
-rw-r--r--gnuradio-core/src/lib/general/gri_float_to_uchar.cc42
-rw-r--r--gnuradio-core/src/lib/general/gri_float_to_uchar.h32
-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.h37
-rw-r--r--gnuradio-core/src/lib/general/gri_lfsr_15_1_0.h57
-rw-r--r--gnuradio-core/src/lib/general/gri_lfsr_32k.h78
-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.h32
-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.h32
-rw-r--r--gnuradio-core/src/lib/general/malloc16.c46
-rw-r--r--gnuradio-core/src/lib/general/malloc16.h35
-rw-r--r--gnuradio-core/src/lib/general/qa_general.cc47
-rw-r--r--gnuradio-core/src/lib/general/qa_general.h37
-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_firdes.cc344
-rw-r--r--gnuradio-core/src/lib/general/qa_gr_firdes.h46
-rw-r--r--gnuradio-core/src/lib/general/qa_gr_fxpt.cc94
-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/random.h32
-rw-r--r--gnuradio-core/src/lib/general/sine_table.h1025
-rw-r--r--gnuradio-core/src/lib/io/Makefile.am96
-rw-r--r--gnuradio-core/src/lib/io/gr_file_descriptor_sink.cc83
-rw-r--r--gnuradio-core/src/lib/io/gr_file_descriptor_sink.h58
-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.cc146
-rw-r--r--gnuradio-core/src/lib/io/gr_file_descriptor_source.h67
-rw-r--r--gnuradio-core/src/lib/io/gr_file_descriptor_source.i35
-rw-r--r--gnuradio-core/src/lib/io/gr_file_sink.cc144
-rw-r--r--gnuradio-core/src/lib/io/gr_file_sink.h75
-rw-r--r--gnuradio-core/src/lib/io/gr_file_sink.i45
-rw-r--r--gnuradio-core/src/lib/io/gr_file_source.cc131
-rw-r--r--gnuradio-core/src/lib/io/gr_file_source.h68
-rw-r--r--gnuradio-core/src/lib/io/gr_file_source.i43
-rw-r--r--gnuradio-core/src/lib/io/gr_message_sink.cc78
-rw-r--r--gnuradio-core/src/lib/io/gr_message_sink.h62
-rw-r--r--gnuradio-core/src/lib/io/gr_message_sink.i36
-rw-r--r--gnuradio-core/src/lib/io/gr_message_source.cc104
-rw-r--r--gnuradio-core/src/lib/io/gr_message_source.h64
-rw-r--r--gnuradio-core/src/lib/io/gr_message_source.i36
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_guts.cc382
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_guts.h116
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_sink.i79
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_sink_f.cc80
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_sink_f.h65
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_sink_x.cc138
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_sink_x.h73
-rw-r--r--gnuradio-core/src/lib/io/gr_trigger_mode.h32
-rw-r--r--gnuradio-core/src/lib/io/gri_logger.cc173
-rw-r--r--gnuradio-core/src/lib/io/gri_logger.h55
-rw-r--r--gnuradio-core/src/lib/io/i2c.cc28
-rw-r--r--gnuradio-core/src/lib/io/i2c.h48
-rw-r--r--gnuradio-core/src/lib/io/i2c_bbio.cc29
-rw-r--r--gnuradio-core/src/lib/io/i2c_bbio.h49
-rw-r--r--gnuradio-core/src/lib/io/i2c_bbio_pp.cc87
-rw-r--r--gnuradio-core/src/lib/io/i2c_bbio_pp.h55
-rw-r--r--gnuradio-core/src/lib/io/i2c_bitbang.cc144
-rw-r--r--gnuradio-core/src/lib/io/i2c_bitbang.h63
-rw-r--r--gnuradio-core/src/lib/io/io.i52
-rw-r--r--gnuradio-core/src/lib/io/microtune_4702.cc183
-rw-r--r--gnuradio-core/src/lib/io/microtune_4702.h69
-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.h47
-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.h66
-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.h48
-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.h64
-rw-r--r--gnuradio-core/src/lib/io/microtune_xxxx_eval_board.cc140
-rw-r--r--gnuradio-core/src/lib/io/microtune_xxxx_eval_board.h96
-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.h61
-rw-r--r--gnuradio-core/src/lib/io/ppio.i48
-rw-r--r--gnuradio-core/src/lib/io/ppio_ppdev.cc221
-rw-r--r--gnuradio-core/src/lib/io/ppio_ppdev.h60
-rw-r--r--gnuradio-core/src/lib/io/sdr_1000.cc65
-rw-r--r--gnuradio-core/src/lib/io/sdr_1000.h51
-rw-r--r--gnuradio-core/src/lib/io/sdr_1000.i36
-rw-r--r--gnuradio-core/src/lib/missing/Makefile.am33
-rw-r--r--gnuradio-core/src/lib/missing/bug_work_around_8.cc2
-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/usleep.c67
-rw-r--r--gnuradio-core/src/lib/omnithread/Makefile.am67
-rw-r--r--gnuradio-core/src/lib/omnithread/dir.mk229
-rw-r--r--gnuradio-core/src/lib/omnithread/mach.cc714
-rw-r--r--gnuradio-core/src/lib/omnithread/nt.cc967
-rw-r--r--gnuradio-core/src/lib/omnithread/omnithread.h622
-rw-r--r--gnuradio-core/src/lib/omnithread/ot_VxThread.h118
-rw-r--r--gnuradio-core/src/lib/omnithread/ot_mach.h51
-rw-r--r--gnuradio-core/src/lib/omnithread/ot_nt.h85
-rw-r--r--gnuradio-core/src/lib/omnithread/ot_posix.h81
-rw-r--r--gnuradio-core/src/lib/omnithread/ot_pthread_nt.h186
-rw-r--r--gnuradio-core/src/lib/omnithread/ot_solaris.h47
-rw-r--r--gnuradio-core/src/lib/omnithread/posix.cc972
-rw-r--r--gnuradio-core/src/lib/omnithread/solaris.cc615
-rw-r--r--gnuradio-core/src/lib/omnithread/threaddata.cc83
-rw-r--r--gnuradio-core/src/lib/omnithread/vxWorks.cc1160
-rw-r--r--gnuradio-core/src/lib/reed-solomon/Makefile.am55
-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.h56
-rw-r--r--gnuradio-core/src/lib/reed-solomon/decode_rs.c262
-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.c126
-rw-r--r--gnuradio-core/src/lib/reed-solomon/fixed.h38
-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.c128
-rw-r--r--gnuradio-core/src/lib/reed-solomon/int.h54
-rw-r--r--gnuradio-core/src/lib/reed-solomon/rs.3170
-rw-r--r--gnuradio-core/src/lib/reed-solomon/rs.h30
-rw-r--r--gnuradio-core/src/lib/reed-solomon/rstest.c117
-rw-r--r--gnuradio-core/src/lib/runtime/Makefile.am109
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.cc131
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.h247
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.i66
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block_detail.cc108
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block_detail.h99
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block_detail.i66
-rw-r--r--gnuradio-core/src/lib/runtime/gr_buffer.cc248
-rw-r--r--gnuradio-core/src/lib/runtime/gr_buffer.h196
-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.cc192
-rw-r--r--gnuradio-core/src/lib/runtime/gr_dispatcher.h67
-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.h114
-rw-r--r--gnuradio-core/src/lib/runtime/gr_error_handler.i69
-rw-r--r--gnuradio-core/src/lib/runtime/gr_io_signature.cc54
-rw-r--r--gnuradio-core/src/lib/runtime/gr_io_signature.h65
-rw-r--r--gnuradio-core/src/lib/runtime/gr_io_signature.i49
-rw-r--r--gnuradio-core/src/lib/runtime/gr_local_sighandler.cc186
-rw-r--r--gnuradio-core/src/lib/runtime/gr_local_sighandler.h60
-rw-r--r--gnuradio-core/src/lib/runtime/gr_message.cc77
-rw-r--r--gnuradio-core/src/lib/runtime/gr_message.h89
-rw-r--r--gnuradio-core/src/lib/runtime/gr_message.i65
-rw-r--r--gnuradio-core/src/lib/runtime/gr_msg_handler.cc30
-rw-r--r--gnuradio-core/src/lib/runtime/gr_msg_handler.h41
-rw-r--r--gnuradio-core/src/lib/runtime/gr_msg_handler.i32
-rw-r--r--gnuradio-core/src/lib/runtime/gr_msg_queue.cc127
-rw-r--r--gnuradio-core/src/lib/runtime/gr_msg_queue.h89
-rw-r--r--gnuradio-core/src/lib/runtime/gr_msg_queue.i111
-rw-r--r--gnuradio-core/src/lib/runtime/gr_pagesize.cc56
-rw-r--r--gnuradio-core/src/lib/runtime/gr_pagesize.h32
-rw-r--r--gnuradio-core/src/lib/runtime/gr_preferences.cc101
-rw-r--r--gnuradio-core/src/lib/runtime/gr_preferences.h32
-rw-r--r--gnuradio-core/src/lib/runtime/gr_realtime.cc71
-rw-r--r--gnuradio-core/src/lib/runtime/gr_realtime.h39
-rw-r--r--gnuradio-core/src/lib/runtime/gr_realtime.i4
-rw-r--r--gnuradio-core/src/lib/runtime/gr_runtime.h44
-rw-r--r--gnuradio-core/src/lib/runtime/gr_select_handler.cc36
-rw-r--r--gnuradio-core/src/lib/runtime/gr_select_handler.h83
-rw-r--r--gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.cc360
-rw-r--r--gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.h61
-rw-r--r--gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.i52
-rw-r--r--gnuradio-core/src/lib/runtime/gr_swig_block_magic.i45
-rw-r--r--gnuradio-core/src/lib/runtime/gr_timer.h82
-rw-r--r--gnuradio-core/src/lib/runtime/gr_tmp_path.cc52
-rw-r--r--gnuradio-core/src/lib/runtime/gr_tmp_path.h31
-rw-r--r--gnuradio-core/src/lib/runtime/gr_types.h63
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf.cc291
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf.h120
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.cc191
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.h74
-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.h65
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.cc198
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.h65
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.cc192
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.h65
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_block.cc89
-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_io_signature.cc55
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_io_signature.h47
-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.cc49
-rw-r--r--gnuradio-core/src/lib/runtime/qa_runtime.h37
-rw-r--r--gnuradio-core/src/lib/runtime/runtime.i49
-rw-r--r--gnuradio-core/src/lib/runtime/test_shared_block_ptr.cc53
-rw-r--r--gnuradio-core/src/lib/swig/Makefile.am111
-rw-r--r--gnuradio-core/src/lib/swig/atsc.i136
-rwxr-xr-xgnuradio-core/src/lib/swig/gen-swig-bug-fix111
-rw-r--r--gnuradio-core/src/lib/swig/gnuradio.i84
-rw-r--r--gnuradio-core/src/lib/swig/shared_ptr.i43
768 files changed, 69006 insertions, 0 deletions
diff --git a/gnuradio-core/src/lib/Makefile.am b/gnuradio-core/src/lib/Makefile.am
new file mode 100644
index 0000000000..2b31b3fcef
--- /dev/null
+++ b/gnuradio-core/src/lib/Makefile.am
@@ -0,0 +1,62 @@
+#
+# Copyright 2001,2004 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+include $(top_srcdir)/Makefile.common
+
+## Process this file with automake to produce Makefile.in
+
+# We've got to build . before swig
+# FIXME add atsc back
+SUBDIRS = missing runtime filter general g72x reed-solomon omnithread io . swig
+
+# generate libgnuradio-core.la from the convenience libraries in subdirs
+
+lib_LTLIBRARIES = libgnuradio-core.la libgnuradio-core-qa.la
+
+libgnuradio_core_la_SOURCES = bug_work_around_6.cc
+libgnuradio_core_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0
+
+libgnuradio_core_qa_la_SOURCES = bug_work_around_6.cc
+libgnuradio_core_qa_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0 \
+ $(LIBGNURADIO_CORE_EXTRA_LDFLAGS)
+
+FIXME = \
+ atsc/libatsc.la
+
+libgnuradio_core_la_LIBADD = \
+ filter/libfilter.la \
+ g72x/libccitt.la \
+ general/libgeneral.la \
+ io/libio.la \
+ missing/libmissing.la \
+ omnithread/libomnithread.la \
+ reed-solomon/librs.la \
+ runtime/libruntime.la \
+ $(FFTW3F_LIBS)
+
+libgnuradio_core_qa_la_LIBADD = \
+ filter/libfilter-qa.la \
+ general/libgeneral-qa.la \
+ runtime/libruntime-qa.la \
+ missing/libmissing.la \
+ libgnuradio-core.la \
+ $(CPPUNIT_LIBS)
+
diff --git a/gnuradio-core/src/lib/bug_work_around_6.cc b/gnuradio-core/src/lib/bug_work_around_6.cc
new file mode 100644
index 0000000000..929c7f81dc
--- /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
+
+static int gr_bug_work_around_6;
diff --git a/gnuradio-core/src/lib/filter/3dnow_float_dotprod_really_simple.S b/gnuradio-core/src/lib/filter/3dnow_float_dotprod_really_simple.S
new file mode 100644
index 0000000000..5aee102f02
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/3dnow_float_dotprod_really_simple.S
@@ -0,0 +1,95 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_4_float_blocks is != 0
+#
+#
+# float
+# sse_float_dotprod (const float *input,
+# const float *taps, unsigned n_4_float_blocks)
+# {
+# float sum0 = 0;
+# float sum1 = 0;
+# float sum2 = 0;
+# float sum3 = 0;
+#
+# do {
+#
+# sum0 += input[0] * taps[0];
+# sum1 += input[1] * taps[1];
+# sum2 += input[2] * taps[2];
+# sum3 += input[3] * taps[3];
+#
+# input += 4;
+# taps += 4;
+#
+# } while (--n_4_float_blocks != 0);
+#
+#
+# return sum0 + sum1 + sum2 + sum3;
+# }
+#
+
+
+ .file "3dnow_float_dotprod_really_simple.s"
+ .version "01.01"
+.text
+ .p2align 4
+.globl sse_float_dotprod
+ .type sse_float_dotprod,@function
+sse_float_dotprod:
+ pushl %ebp
+ movl %esp, %ebp
+ movl 8(%ebp), %edx
+ movl 12(%ebp), %eax
+ movl 16(%ebp), %ecx
+
+
+ # The plan is to get it computing the correct answer, and
+ # then to unroll and schedule the inner loop.
+
+ pxor %mm4, %mm4 # mm4 = 0 0
+ shll $1, %ecx # count * 2
+
+ .p2align 4
+.loop1:
+ movq (%eax), %mm0
+ pfmul (%edx), %mm0
+ pfadd %mm0, %mm4
+ addl $8, %edx
+ addl $8, %eax
+ decl %ecx
+ jne .loop1
+
+ # at this point mm4 contains partial sums
+
+ pfacc %mm4, %mm4
+ movd %mm4, 16(%ebp)
+ femms
+ flds 16(%ebp)
+
+ popl %ebp
+ ret
+.Lfe1:
+ .size sse_float_dotprod,.Lfe1-sse_float_dotprod
+ .ident "Hand coded x86 3DNow! assembly"
diff --git a/gnuradio-core/src/lib/filter/3dnow_float_dotprod_simple.S b/gnuradio-core/src/lib/filter/3dnow_float_dotprod_simple.S
new file mode 100644
index 0000000000..4c4936d315
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/3dnow_float_dotprod_simple.S
@@ -0,0 +1,102 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_4_float_blocks is != 0
+#
+#
+# float
+# sse_float_dotprod (const float *input,
+# const float *taps, unsigned n_4_float_blocks)
+# {
+# float sum0 = 0;
+# float sum1 = 0;
+# float sum2 = 0;
+# float sum3 = 0;
+#
+# do {
+#
+# sum0 += input[0] * taps[0];
+# sum1 += input[1] * taps[1];
+# sum2 += input[2] * taps[2];
+# sum3 += input[3] * taps[3];
+#
+# input += 4;
+# taps += 4;
+#
+# } while (--n_4_float_blocks != 0);
+#
+#
+# return sum0 + sum1 + sum2 + sum3;
+# }
+#
+
+
+ .file "3dnow_float_dotprod_simple.s"
+ .version "01.01"
+.text
+ .p2align 4
+.globl sse_float_dotprod
+ .type sse_float_dotprod,@function
+sse_float_dotprod:
+ pushl %ebp
+ movl %esp, %ebp
+ movl 8(%ebp), %edx
+ movl 12(%ebp), %eax
+ movl 16(%ebp), %ecx
+
+
+ # The plan is to get it computing the correct answer, and
+ # then to unroll and schedule the inner loop.
+
+ pxor %mm4, %mm4 # mm4 = 0 0
+ pxor %mm5, %mm5 # mm5 = 0 0
+
+ .p2align 4
+.loop1:
+ movq 0(%eax), %mm0
+ movq 8(%eax), %mm1
+
+ pfmul 0(%edx), %mm0
+ pfadd %mm0, %mm4
+
+ pfmul 8(%edx), %mm1
+ pfadd %mm1, %mm5
+
+ addl $16, %edx
+ addl $16, %eax
+ decl %ecx
+ jne .loop1
+
+ # at this point mm4 and mm5 contain partial sums
+
+ pfadd %mm5, %mm4
+ pfacc %mm4, %mm4
+ movd %mm4, 16(%ebp)
+ femms
+ flds 16(%ebp)
+
+ popl %ebp
+ ret
+.Lfe1:
+ .size sse_float_dotprod,.Lfe1-sse_float_dotprod
+ .ident "Hand coded x86 3DNow! assembly"
diff --git a/gnuradio-core/src/lib/filter/Makefile.am b/gnuradio-core/src/lib/filter/Makefile.am
new file mode 100644
index 0000000000..01885a8490
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/Makefile.am
@@ -0,0 +1,306 @@
+#
+# Copyright 2001,2002,2004,2005,2006 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+include $(top_srcdir)/Makefile.common
+
+#
+# This directory contains mostly filter routines, plus a few
+# other performance critical items
+#
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(CPPUNIT_INCLUDES)
+
+noinst_LTLIBRARIES = libfilter.la libfilter-qa.la
+
+# ----------------------------------------------------------------
+# these scripts generate FIR code
+#
+
+CODE_GENERATOR = \
+ generate_all.py \
+ generate_gr_fir_XXX.py \
+ generate_gr_fir_filter_XXX.py \
+ generate_gr_interp_fir_filter_XXX.py \
+ generate_gr_rational_resampler_base_XXX.py \
+ generate_gr_fir_sysconfig.py \
+ generate_gr_fir_sysconfig_generic.py \
+ generate_gr_fir_util.py \
+ generate_gr_freq_xlating_fir_filter_XXX.py \
+ generate_utils.py \
+ gr_fir_XXX.cc.t \
+ gr_fir_XXX.h.t \
+ gr_fir_XXX_generic.cc.t \
+ gr_fir_XXX_generic.h.t \
+ gr_fir_filter_XXX.cc.t \
+ gr_fir_filter_XXX.h.t \
+ gr_fir_filter_XXX.i.t \
+ gr_interp_fir_filter_XXX.cc.t \
+ gr_interp_fir_filter_XXX.h.t \
+ gr_interp_fir_filter_XXX.i.t \
+ gr_rational_resampler_base_XXX.cc.t \
+ gr_rational_resampler_base_XXX.h.t \
+ gr_rational_resampler_base_XXX.i.t \
+ gr_freq_xlating_fir_filter_XXX.cc.t \
+ gr_freq_xlating_fir_filter_XXX.h.t \
+ gr_freq_xlating_fir_filter_XXX.i.t
+
+
+
+# include $(srcdir)/Makefile.gen
+include Makefile.gen
+
+
+$(GENERATED_H) $(GENERATED_I) $(GENERATED_CC): $(CODE_GENERATOR)
+ PYTHONPATH=$(top_srcdir)/gnuradio-core/src/python srcdir=$(srcdir) $(srcdir)/generate_all.py
+
+
+BUILT_SOURCES = $(GENERATED_H) $(GENERATED_I) $(GENERATED_CC)
+
+
+# ----------------------------------------------------------------
+# MD_CPU and MD_SUBCPU are set at configure time by way of
+# gnuradio/config/gr_set_md_cpu.m4.
+# It indicates which set of machine dependent code we should be building.
+# We currently implement "generic" and "x86"
+
+#
+# <foo>_CODE entry for each set of machine specific speedups
+#
+
+generic_CODE = \
+ sysconfig_generic.cc
+
+generic_qa_CODE = \
+ qa_dotprod_generic.cc
+
+x86_CODE = \
+ sysconfig_x86.cc \
+ gr_fir_sysconfig_x86.cc \
+ gr_cpu.cc \
+ gr_fir_ccc_simd.cc \
+ gr_fir_ccc_x86.cc \
+ gr_fir_fff_simd.cc \
+ gr_fir_fff_x86.cc \
+ gr_fir_fsf_simd.cc \
+ gr_fir_fsf_x86.cc \
+ gr_fir_scc_simd.cc \
+ gr_fir_scc_x86.cc \
+ gr_fir_fcc_simd.cc \
+ gr_fir_fcc_x86.cc \
+ gr_fir_ccf_simd.cc \
+ gr_fir_ccf_x86.cc \
+ sse_debug.c
+
+x86_SUBCODE = \
+ float_dotprod_sse.S \
+ float_dotprod_3dnow.S \
+ complex_dotprod_3dnowext.S \
+ complex_dotprod_3dnow.S \
+ complex_dotprod_sse.S \
+ ccomplex_dotprod_3dnowext.S \
+ ccomplex_dotprod_3dnow.S \
+ ccomplex_dotprod_sse.S \
+ fcomplex_dotprod_3dnow.S \
+ fcomplex_dotprod_sse.S \
+ short_dotprod_mmx.S \
+ cpuid_x86.S
+
+x86_64_SUBCODE = \
+ float_dotprod_sse64.S \
+ float_dotprod_3dnow64.S \
+ complex_dotprod_3dnowext64.S \
+ complex_dotprod_3dnow64.S \
+ complex_dotprod_sse64.S \
+ ccomplex_dotprod_3dnowext64.S \
+ ccomplex_dotprod_3dnow64.S \
+ ccomplex_dotprod_sse64.S \
+ fcomplex_dotprod_3dnow64.S \
+ fcomplex_dotprod_sse64.S \
+ short_dotprod_mmx64.S \
+ cpuid_x86_64.S
+
+x86_qa_CODE = \
+ qa_dotprod_x86.cc \
+ qa_float_dotprod_x86.cc \
+ qa_complex_dotprod_x86.cc \
+ qa_ccomplex_dotprod_x86.cc
+
+#
+# include each <foo>_CODE entry here...
+#
+EXTRA_libfilter_la_SOURCES = \
+ $(generic_CODE) \
+ $(generic_qa_CODE) \
+ $(x86_CODE) \
+ $(x86_SUBCODE) \
+ $(x86_64_SUBCODE) \
+ $(x86_qa_CODE)
+
+
+EXTRA_DIST = \
+ 3dnow_float_dotprod_really_simple.S \
+ 3dnow_float_dotprod_simple.S \
+ $(CODE_GENERATOR)
+
+
+# work around automake deficiency
+libfilter_la_common_SOURCES = \
+ $(GENERATED_CC) \
+ gr_adaptive_fir_ccf.cc \
+ gr_cma_equalizer_cc.cc \
+ gr_fft_filter_ccc.cc \
+ gr_fft_filter_fff.cc \
+ gr_goertzel_fc.cc \
+ gr_filter_delay_fc.cc \
+ gr_fractional_interpolator.cc \
+ gr_hilbert_fc.cc \
+ gr_iir_filter_ffd.cc \
+ gr_sincos.c \
+ gr_single_pole_iir_filter_ff.cc \
+ gr_single_pole_avg_filter_ff.cc \
+ gr_single_pole_rec_filter_ff.cc \
+ gr_single_zero_avg_filter_ff.cc \
+ gr_single_zero_rec_filter_ff.cc \
+ gr_single_pole_iir_filter_cc.cc \
+ gri_goertzel.cc \
+ gri_mmse_fir_interpolator.cc \
+ gri_mmse_fir_interpolator_cc.cc \
+ complex_dotprod_generic.cc \
+ ccomplex_dotprod_generic.cc \
+ float_dotprod_generic.c \
+ short_dotprod_generic.c
+
+libfilter_qa_la_common_SOURCES = \
+ qa_filter.cc \
+ qa_gr_fir_ccf.cc \
+ qa_gr_fir_fcc.cc \
+ qa_gr_fir_fff.cc \
+ qa_gr_fir_ccc.cc \
+ qa_gr_fir_scc.cc \
+ qa_gri_mmse_fir_interpolator.cc
+
+if MD_CPU_generic
+libfilter_la_SOURCES = $(libfilter_la_common_SOURCES) $(generic_CODE)
+libfilter_qa_la_SOURCES = $(libfilter_qa_la_common_SOURCES) $(generic_qa_CODE)
+endif
+
+if MD_CPU_x86
+if MD_SUBCPU_x86_64
+libfilter_la_SOURCES = $(libfilter_la_common_SOURCES) $(x86_64_SUBCODE) $(x86_CODE)
+else
+libfilter_la_SOURCES = $(libfilter_la_common_SOURCES) $(x86_SUBCODE) $(x86_CODE)
+endif
+
+libfilter_qa_la_SOURCES = $(libfilter_qa_la_common_SOURCES) $(x86_qa_CODE)
+endif
+
+
+grinclude_HEADERS = \
+ $(GENERATED_H) \
+ complex_dotprod_generic.h \
+ complex_dotprod_x86.h \
+ fcomplex_dotprod_x86.h \
+ ccomplex_dotprod_generic.h \
+ ccomplex_dotprod_x86.h \
+ float_dotprod_generic.h \
+ float_dotprod_x86.h \
+ gr_adaptive_fir_ccf.h \
+ gr_cma_equalizer_cc.h \
+ gr_cpu.h \
+ gr_fft_filter_ccc.h \
+ gr_fft_filter_fff.h \
+ gr_filter_delay_fc.h \
+ gr_fir_sysconfig_x86.h \
+ gr_fractional_interpolator.h \
+ gr_goertzel_fc.h \
+ gr_hilbert_fc.h \
+ gr_iir_filter_ffd.h \
+ gr_rotator.h \
+ gr_sincos.h \
+ gr_single_pole_avg.h \
+ gr_single_pole_rec.h \
+ gr_single_pole_iir.h \
+ gr_single_pole_iir_filter_ff.h \
+ gr_single_pole_avg_filter_ff.h \
+ gr_single_pole_rec_filter_ff.h \
+ gr_single_zero_avg_filter_ff.h \
+ gr_single_zero_rec_filter_ff.h \
+ gr_single_pole_iir_filter_cc.h \
+ gr_single_zero_avg.h \
+ gr_single_zero_rec.h \
+ gri_goertzel.h \
+ gri_iir.h \
+ gri_mmse_fir_interpolator.h \
+ gri_mmse_fir_interpolator_cc.h \
+ qa_filter.h \
+ short_dotprod_generic.h \
+ short_dotprod_x86.h \
+ sse_debug.h
+
+noinst_HEADERS = \
+ assembly.h \
+ gr_fir_scc_simd.h \
+ gr_fir_scc_x86.h \
+ gr_fir_fcc_simd.h \
+ gr_fir_fcc_x86.h \
+ gr_fir_ccf_simd.h \
+ gr_fir_ccf_x86.h \
+ gr_fir_ccc_simd.h \
+ gr_fir_ccc_x86.h \
+ gr_fir_fff_simd.h \
+ gr_fir_fff_x86.h \
+ gr_fir_fsf_simd.h \
+ gr_fir_fsf_x86.h \
+ interpolator_taps.h \
+ qa_complex_dotprod_x86.h \
+ qa_ccomplex_dotprod_x86.h \
+ qa_dotprod.h \
+ qa_float_dotprod_x86.h \
+ qa_gr_fir_ccf.h \
+ qa_gr_fir_fcc.h \
+ qa_gr_fir_fff.h \
+ qa_gr_fir_ccc.h \
+ qa_gr_fir_scc.h \
+ qa_gri_mmse_fir_interpolator.h
+
+
+
+swiginclude_HEADERS = \
+ filter.i \
+ filter_generated.i \
+ gr_adaptive_fir_ccf.i \
+ gr_cma_equalizer_cc.i \
+ gr_fft_filter_ccc.i \
+ gr_fft_filter_fff.i \
+ gr_filter_delay_fc.i \
+ gr_goertzel_fc.i \
+ gr_hilbert_fc.i \
+ gr_iir_filter_ffd.i \
+ gr_single_pole_iir_filter_ff.i \
+ gr_single_pole_avg_filter_ff.i \
+ gr_single_pole_rec_filter_ff.i \
+ gr_single_zero_avg_filter_ff.i \
+ gr_single_zero_rec_filter_ff.i \
+ gr_single_pole_iir_filter_cc.i \
+ $(GENERATED_I)
+
+
+CLEANFILES = $(BUILT_SOURCES) *.pyc
diff --git a/gnuradio-core/src/lib/filter/Makefile.gen b/gnuradio-core/src/lib/filter/Makefile.gen
new file mode 100644
index 0000000000..6809274fa9
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/Makefile.gen
@@ -0,0 +1,111 @@
+#
+# This file is machine generated. All edits will be overwritten
+#
+GENERATED_H = \
+ gr_fir_ccc.h \
+ gr_fir_ccc_generic.h \
+ gr_fir_ccf.h \
+ gr_fir_ccf_generic.h \
+ gr_fir_fcc.h \
+ gr_fir_fcc_generic.h \
+ gr_fir_fff.h \
+ gr_fir_fff_generic.h \
+ gr_fir_filter_ccc.h \
+ gr_fir_filter_ccf.h \
+ gr_fir_filter_fcc.h \
+ gr_fir_filter_fff.h \
+ gr_fir_filter_fsf.h \
+ gr_fir_filter_scc.h \
+ gr_fir_fsf.h \
+ gr_fir_fsf_generic.h \
+ gr_fir_scc.h \
+ gr_fir_scc_generic.h \
+ gr_fir_sysconfig.h \
+ gr_fir_sysconfig_generic.h \
+ gr_fir_util.h \
+ gr_freq_xlating_fir_filter_ccc.h \
+ gr_freq_xlating_fir_filter_ccf.h \
+ gr_freq_xlating_fir_filter_fcc.h \
+ gr_freq_xlating_fir_filter_fcf.h \
+ gr_freq_xlating_fir_filter_scc.h \
+ gr_freq_xlating_fir_filter_scf.h \
+ gr_interp_fir_filter_ccc.h \
+ gr_interp_fir_filter_ccf.h \
+ gr_interp_fir_filter_fcc.h \
+ gr_interp_fir_filter_fff.h \
+ gr_interp_fir_filter_fsf.h \
+ gr_interp_fir_filter_scc.h \
+ gr_rational_resampler_base_ccc.h \
+ gr_rational_resampler_base_ccf.h \
+ gr_rational_resampler_base_fcc.h \
+ gr_rational_resampler_base_fff.h \
+ gr_rational_resampler_base_fsf.h \
+ gr_rational_resampler_base_scc.h
+
+GENERATED_I = \
+ gr_fir_filter_ccc.i \
+ gr_fir_filter_ccf.i \
+ gr_fir_filter_fcc.i \
+ gr_fir_filter_fff.i \
+ gr_fir_filter_fsf.i \
+ gr_fir_filter_scc.i \
+ gr_freq_xlating_fir_filter_ccc.i \
+ gr_freq_xlating_fir_filter_ccf.i \
+ gr_freq_xlating_fir_filter_fcc.i \
+ gr_freq_xlating_fir_filter_fcf.i \
+ gr_freq_xlating_fir_filter_scc.i \
+ gr_freq_xlating_fir_filter_scf.i \
+ gr_interp_fir_filter_ccc.i \
+ gr_interp_fir_filter_ccf.i \
+ gr_interp_fir_filter_fcc.i \
+ gr_interp_fir_filter_fff.i \
+ gr_interp_fir_filter_fsf.i \
+ gr_interp_fir_filter_scc.i \
+ gr_rational_resampler_base_ccc.i \
+ gr_rational_resampler_base_ccf.i \
+ gr_rational_resampler_base_fcc.i \
+ gr_rational_resampler_base_fff.i \
+ gr_rational_resampler_base_fsf.i \
+ gr_rational_resampler_base_scc.i
+
+GENERATED_CC = \
+ gr_fir_ccc.cc \
+ gr_fir_ccc_generic.cc \
+ gr_fir_ccf.cc \
+ gr_fir_ccf_generic.cc \
+ gr_fir_fcc.cc \
+ gr_fir_fcc_generic.cc \
+ gr_fir_fff.cc \
+ gr_fir_fff_generic.cc \
+ gr_fir_filter_ccc.cc \
+ gr_fir_filter_ccf.cc \
+ gr_fir_filter_fcc.cc \
+ gr_fir_filter_fff.cc \
+ gr_fir_filter_fsf.cc \
+ gr_fir_filter_scc.cc \
+ gr_fir_fsf.cc \
+ gr_fir_fsf_generic.cc \
+ gr_fir_scc.cc \
+ gr_fir_scc_generic.cc \
+ gr_fir_sysconfig.cc \
+ gr_fir_sysconfig_generic.cc \
+ gr_fir_util.cc \
+ gr_freq_xlating_fir_filter_ccc.cc \
+ gr_freq_xlating_fir_filter_ccf.cc \
+ gr_freq_xlating_fir_filter_fcc.cc \
+ gr_freq_xlating_fir_filter_fcf.cc \
+ gr_freq_xlating_fir_filter_scc.cc \
+ gr_freq_xlating_fir_filter_scf.cc \
+ gr_interp_fir_filter_ccc.cc \
+ gr_interp_fir_filter_ccf.cc \
+ gr_interp_fir_filter_fcc.cc \
+ gr_interp_fir_filter_fff.cc \
+ gr_interp_fir_filter_fsf.cc \
+ gr_interp_fir_filter_scc.cc \
+ gr_rational_resampler_base_ccc.cc \
+ gr_rational_resampler_base_ccf.cc \
+ gr_rational_resampler_base_fcc.cc \
+ gr_rational_resampler_base_fff.cc \
+ gr_rational_resampler_base_fsf.cc \
+ gr_rational_resampler_base_scc.cc
+
diff --git a/gnuradio-core/src/lib/filter/README b/gnuradio-core/src/lib/filter/README
new file mode 100644
index 0000000000..00730f8338
--- /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 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+This directory holds filtering code, some of which is machine
+generated. Which variations are generated is controlled by two
+variables. For most everything, the global "signatures"
+in generate_utils.py controls.
+
+For GrFreqXlatingFIRfilter<foo>, the global "fx_signatures" in
+generate_GrFreqXlatingFIRfilterXXX.py controls.
diff --git a/gnuradio-core/src/lib/filter/assembly.h b/gnuradio-core/src/lib/filter/assembly.h
new file mode 100644
index 0000000000..9398a0a1e8
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/assembly.h
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _ASSEMBLY_H_
+#define _ASSEMBLY_H_
+
+
+
+#ifndef __ELF__
+
+/*
+ * Too bad, the following define does not work as expected --SF
+ * #define GLOB_SYMB(f) __USER_LABEL_PREFIX__ ## f
+ */
+#define GLOB_SYMB(f) _ ## f
+
+#define DEF_FUNC_HEAD(f) \
+ .def GLOB_SYMB(f); .scl 2; .type 32; .endef
+
+#define FUNC_TAIL(f) /* none */
+
+
+#else /* !__ELF__ */
+
+
+#define GLOB_SYMB(f) f
+
+#define DEF_FUNC_HEAD(f) \
+ .type GLOB_SYMB(f),@function \
+
+#define FUNC_TAIL(f) \
+ .Lfe1: \
+ .size GLOB_SYMB(f),.Lfe1-GLOB_SYMB(f)
+
+
+#endif /* !__ELF__ */
+
+
+#endif /* _ASSEMBLY_H_ */
diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow.S b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow.S
new file mode 100644
index 0000000000..79826e8a3c
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow.S
@@ -0,0 +1,216 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_ccomplex_blocks is != 0
+#
+#
+# ccomplex_dotprod_generic (const float *input,
+# const float *taps, unsigned n_2_ccomplex_blocks, float *result)
+# {
+# float sum0 = 0;
+# float sum1 = 0;
+# float sum2 = 0;
+# float sum3 = 0;
+#
+# do {
+#
+# sum0 += input[0] * taps[0] - input[1] * taps[1];
+# sum1 += input[0] * taps[1] + input[1] * taps[0];
+# sum2 += input[2] * taps[2] - input[3] * taps[3];
+# sum3 += input[2] * taps[3] + input[3] * taps[2];
+#
+# input += 4;
+# taps += 4;
+#
+# } while (--n_2_ccomplex_blocks != 0);
+#
+#
+# result[0] = sum0 + sum2;
+# result[1] = sum1 + sum3;
+# }
+#
+
+# TODO: prefetch and better scheduling
+
+#include "assembly.h"
+
+ .file "ccomplex_dotprod_3dnow.S"
+ .version "01.01"
+.text
+ .p2align 4
+.globl GLOB_SYMB(ccomplex_dotprod_3dnow)
+ DEF_FUNC_HEAD(ccomplex_dotprod_3dnow)
+GLOB_SYMB(ccomplex_dotprod_3dnow):
+ pushl %ebp
+ movl %esp, %ebp
+ movl 8(%ebp), %eax # input
+ movl 12(%ebp), %edx # taps
+ movl 16(%ebp), %ecx # n_2_ccomplex_blocks
+
+ # zero accumulators
+
+ pxor %mm6, %mm6 # mm6 = 0 0
+
+ movq 0(%eax), %mm0
+
+ pxor %mm7, %mm7 # mm7 = 0 0
+
+ movq 0(%edx), %mm2
+
+ movq 8(%eax), %mm1
+
+ shrl $1, %ecx # ecx = n_2_ccomplex_blocks / 2
+
+ movq 8(%edx), %mm3
+
+ jmp .L1_test
+
+ #
+ # 4 taps / loop
+ # something like ?? cycles / loop
+ #
+
+ .p2align 4
+.loop1:
+
+# complex prod: C += A * B, w/ temp Z, mmPN=$80000000
+#
+# movq (%eax), %mmA
+# movq (%edx), %mmB
+#
+# # 3DNow! replacement for: pswapd %mmA, %mmZ
+# # TODO: optimize the punpckhdq
+# movq %mmA, %mmZ
+# punpckhdq %mmZ, %mmZ
+# punpckldq %mmA, %mmZ
+#
+# pfmul %mmB, %mmA
+# pfmul %mmZ, %mmB
+#
+# # 3DNow! replacement for: pfpnacc %mmB, %mmA
+# pxor %mmPN, %mmA
+# pfacc %mmB, %mmA
+#
+# pfadd %mmA, %mmC
+
+
+# A=mm0, B=mm2, Z=mm4
+# A'=mm1, B'=mm3, Z'=mm5
+
+ movq %mm0, %mm4
+ movq %mm1, %mm5
+ punpckhdq %mm4, %mm4
+ punpckhdq %mm5, %mm5
+ punpckldq %mm0, %mm4
+ pfmul %mm2, %mm0
+ punpckldq %mm1, %mm5
+ pfmul %mm4, %mm2
+ pfadd %mm0, %mm6
+ movq 16(%edx), %mm0
+ pfmul %mm3, %mm1
+ pfadd %mm2, %mm7
+ movq 16(%eax), %mm2
+ pfadd %mm1, %mm6
+ pfmul %mm5, %mm3
+ movq 24(%edx), %mm1
+
+ movq %mm0, %mm4
+ movq %mm1, %mm5
+
+ pfadd %mm3, %mm7
+ movq 24(%eax), %mm3
+
+# unroll
+
+ punpckhdq %mm4, %mm4
+ punpckhdq %mm5, %mm5
+ punpckldq %mm0, %mm4
+ pfmul %mm2, %mm0
+ punpckldq %mm1, %mm5
+ pfmul %mm4, %mm2
+ pfadd %mm0, %mm6
+ movq 32(%edx), %mm0
+ pfmul %mm3, %mm1
+ pfadd %mm2, %mm7
+ movq 32(%eax), %mm2
+ pfadd %mm1, %mm6
+ pfmul %mm5, %mm3
+ movq 40(%edx), %mm1
+
+ addl $32, %eax
+ addl $32, %edx
+
+ pfadd %mm3, %mm7
+ movq 8(%eax), %mm3
+
+.L1_test:
+ decl %ecx
+ jge .loop1
+
+ # We've handled the bulk of multiplies up to here.
+ # Let's see if original n_2_ccomplex_blocks was odd.
+ # If so, we've got 2 more taps to do.
+
+ movl 16(%ebp), %ecx # n_2_ccomplex_blocks
+ andl $1, %ecx
+ je .Leven
+
+ # The count was odd, do 2 more taps.
+ # Note that we've already got mm0/mm2 & mm1/mm3 preloaded
+ # from the main loop.
+
+ movq %mm0, %mm4
+ movq %mm1, %mm5
+ punpckhdq %mm4, %mm4
+ punpckhdq %mm5, %mm5
+ punpckldq %mm0, %mm4
+ pfmul %mm2, %mm0
+ punpckldq %mm1, %mm5
+ pfmul %mm4, %mm2
+ pfadd %mm0, %mm6
+ pfmul %mm3, %mm1
+ pfadd %mm2, %mm7
+ pfmul %mm5, %mm3
+ pfadd %mm1, %mm6
+ pfadd %mm3, %mm7
+
+.Leven:
+ # mmNP: negative inversor
+
+ pcmpeqd %mm0, %mm0 # set all bits to 1
+ psllq $63, %mm0 # keep only hsb
+
+ pxor %mm0, %mm6
+ pfacc %mm7, %mm6
+
+ movl 20(%ebp), %eax # result
+ movq %mm6, (%eax)
+
+ femms
+
+ popl %ebp
+ ret
+
+FUNC_TAIL(ccomplex_dotprod_3dnow)
+ .ident "Hand coded x86 3DNow! assembly"
+
diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow64.S b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow64.S
new file mode 100644
index 0000000000..bff045e113
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow64.S
@@ -0,0 +1,213 @@
+#
+# Copyright 2002,2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_ccomplex_blocks is != 0
+#
+#
+# ccomplex_dotprod_generic (const float *input,
+# const float *taps, unsigned n_2_ccomplex_blocks, float *result)
+# {
+# float sum0 = 0;
+# float sum1 = 0;
+# float sum2 = 0;
+# float sum3 = 0;
+#
+# do {
+#
+# sum0 += input[0] * taps[0] - input[1] * taps[1];
+# sum1 += input[0] * taps[1] + input[1] * taps[0];
+# sum2 += input[2] * taps[2] - input[3] * taps[3];
+# sum3 += input[2] * taps[3] + input[3] * taps[2];
+#
+# input += 4;
+# taps += 4;
+#
+# } while (--n_2_ccomplex_blocks != 0);
+#
+#
+# result[0] = sum0 + sum2;
+# result[1] = sum1 + sum3;
+# }
+#
+
+# TODO: prefetch and better scheduling
+
+#include "assembly.h"
+
+
+ .file "ccomplex_dotprod_3dnow64.S"
+ .version "01.01"
+.text
+ .p2align 4
+.globl GLOB_SYMB(ccomplex_dotprod_3dnow)
+ DEF_FUNC_HEAD(ccomplex_dotprod_3dnow)
+GLOB_SYMB(ccomplex_dotprod_3dnow):
+
+ # intput: rdi, taps: rsi, n_2_ccomplex_blocks: rdx, result: rcx
+
+ mov %rdx, %rax
+
+ # zero accumulators
+
+ pxor %mm6, %mm6 # mm6 = 0 0
+
+ movq 0(%rdi), %mm0
+
+ pxor %mm7, %mm7 # mm7 = 0 0
+
+ movq 0(%rsi), %mm2
+
+ movq 8(%rdi), %mm1
+
+ shr $1, %rax # rax = n_2_ccomplex_blocks / 2
+
+ movq 8(%rsi), %mm3
+
+ jmp .L1_test
+
+ #
+ # 4 taps / loop
+ # something like ?? cycles / loop
+ #
+
+ .p2align 4
+.loop1:
+
+# complex prod: C += A * B, w/ temp Z, mmPN=$80000000
+#
+# movq (%rdx), %mmA
+# movq (%rsi), %mmB
+#
+# # 3DNow! replacement for: pswapd %mmA, %mmZ
+# # TODO: optimize the punpckhdq
+# movq %mmA, %mmZ
+# punpckhdq %mmZ, %mmZ
+# punpckldq %mmA, %mmZ
+#
+# pfmul %mmB, %mmA
+# pfmul %mmZ, %mmB
+#
+# # 3DNow! replacement for: pfpnacc %mmB, %mmA
+# pxor %mmPN, %mmA
+# pfacc %mmB, %mmA
+#
+# pfadd %mmA, %mmC
+
+
+# A=mm0, B=mm2, Z=mm4
+# A'=mm1, B'=mm3, Z'=mm5
+
+ movq %mm0, %mm4
+ movq %mm1, %mm5
+ punpckhdq %mm4, %mm4
+ punpckhdq %mm5, %mm5
+ punpckldq %mm0, %mm4
+ pfmul %mm2, %mm0
+ punpckldq %mm1, %mm5
+ pfmul %mm4, %mm2
+ pfadd %mm0, %mm6
+ movq 16(%rsi), %mm0
+ pfmul %mm3, %mm1
+ pfadd %mm2, %mm7
+ movq 16(%rdi), %mm2
+ pfadd %mm1, %mm6
+ pfmul %mm5, %mm3
+ movq 24(%rsi), %mm1
+
+ movq %mm0, %mm4
+ movq %mm1, %mm5
+
+ pfadd %mm3, %mm7
+ movq 24(%rdi), %mm3
+
+# unroll
+
+ punpckhdq %mm4, %mm4
+ punpckhdq %mm5, %mm5
+ punpckldq %mm0, %mm4
+ pfmul %mm2, %mm0
+ punpckldq %mm1, %mm5
+ pfmul %mm4, %mm2
+ pfadd %mm0, %mm6
+ movq 32(%rsi), %mm0
+ pfmul %mm3, %mm1
+ pfadd %mm2, %mm7
+ movq 32(%rdi), %mm2
+ pfadd %mm1, %mm6
+ pfmul %mm5, %mm3
+ movq 40(%rsi), %mm1
+
+ add $32, %rdi
+ add $32, %rsi
+
+ pfadd %mm3, %mm7
+ movq 8(%rdi), %mm3
+
+.L1_test:
+ dec %rax
+ jge .loop1
+
+ # We've handled the bulk of multiplies up to here.
+ # Let's see if original n_2_ccomplex_blocks was odd.
+ # If so, we've got 2 more taps to do.
+
+ and $1, %rdx
+ je .Leven
+
+ # The count was odd, do 2 more taps.
+ # Note that we've already got mm0/mm2 & mm1/mm3 preloaded
+ # from the main loop.
+
+ movq %mm0, %mm4
+ movq %mm1, %mm5
+ punpckhdq %mm4, %mm4
+ punpckhdq %mm5, %mm5
+ punpckldq %mm0, %mm4
+ pfmul %mm2, %mm0
+ punpckldq %mm1, %mm5
+ pfmul %mm4, %mm2
+ pfadd %mm0, %mm6
+ pfmul %mm3, %mm1
+ pfadd %mm2, %mm7
+ pfmul %mm5, %mm3
+ pfadd %mm1, %mm6
+ pfadd %mm3, %mm7
+
+.Leven:
+ # mmNP: negative inversor
+
+ pcmpeqd %mm0, %mm0 # set all bits to 1
+ psllq $63, %mm0 # keep only hsb
+
+ pxor %mm0, %mm6
+ pfacc %mm7, %mm6
+
+ movq %mm6, (%rcx)
+
+ femms
+
+ retq
+
+FUNC_TAIL(ccomplex_dotprod_3dnow)
+ .ident "Hand coded x86_64 3DNow! assembly"
+
diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext.S b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext.S
new file mode 100644
index 0000000000..39057e46ed
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext.S
@@ -0,0 +1,191 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_ccomplex_blocks is != 0
+#
+#
+# ccomplex_dotprod_generic (const float *input,
+# const float *taps, unsigned n_2_ccomplex_blocks, float *result)
+# {
+# float sum0 = 0;
+# float sum1 = 0;
+# float sum2 = 0;
+# float sum3 = 0;
+#
+# do {
+#
+# sum0 += input[0] * taps[0] - input[1] * taps[1];
+# sum1 += input[0] * taps[1] + input[1] * taps[0];
+# sum2 += input[2] * taps[2] - input[3] * taps[3];
+# sum3 += input[2] * taps[3] + input[3] * taps[2];
+#
+# input += 4;
+# taps += 4;
+#
+# } while (--n_2_ccomplex_blocks != 0);
+#
+#
+# result[0] = sum0 + sum2;
+# result[1] = sum1 + sum3;
+# }
+#
+
+# TODO: prefetch and better scheduling
+
+#include "assembly.h"
+
+ .file "ccomplex_dotprod_3dnowext.S"
+ .version "01.01"
+.text
+ .p2align 4
+.globl GLOB_SYMB(ccomplex_dotprod_3dnowext)
+ DEF_FUNC_HEAD(ccomplex_dotprod_3dnowext)
+GLOB_SYMB(ccomplex_dotprod_3dnowext):
+ pushl %ebp
+ movl %esp, %ebp
+ movl 8(%ebp), %eax # input
+ movl 12(%ebp), %edx # taps
+ movl 16(%ebp), %ecx # n_2_ccomplex_blocks
+
+ # zero accumulators
+
+ pxor %mm6, %mm6 # mm6 = 0 0
+ pxor %mm7, %mm7 # mm7 = 0 0
+
+ movq 0(%eax), %mm0
+ movq 0(%edx), %mm2
+
+ shrl $1, %ecx # ecx = n_2_ccomplex_blocks / 2
+
+ movq 8(%eax), %mm1
+ movq 8(%edx), %mm3
+
+
+ jmp .L1_test
+
+ #
+ # 4 taps / loop
+ # something like ?? cycles / loop
+ #
+
+ .p2align 4
+.loop1:
+
+# complex prod: C += A * B, w/ temp Z
+#
+# movq 0(%eax), %mmA
+# movq 0(%edx), %mmB
+# pswapd %mmA, %mmZ
+# pfmul %mmB, %mmA
+# pfmul %mmZ, %mmB
+# pfpnacc %mmB, %mmA
+# pfadd %mmA, %mmC
+
+
+# A=mm0, B=mm2, Z=mm4
+# A'=mm1, B'=mm3, Z'=mm5
+
+ pswapd %mm0, %mm4
+ pfmul %mm2, %mm0
+ pswapd %mm1, %mm5
+ pfmul %mm4, %mm2
+ pfmul %mm3, %mm1
+ pfpnacc %mm2, %mm0
+ pfmul %mm5, %mm3
+ movq 16(%edx), %mm2
+ pfpnacc %mm3, %mm1
+ movq 24(%edx), %mm3
+
+ pfadd %mm0, %mm6
+ movq 16(%eax), %mm0
+ pfadd %mm1, %mm7
+ movq 24(%eax), %mm1
+
+# unroll
+
+ pswapd %mm0, %mm4
+ pfmul %mm2, %mm0
+ pswapd %mm1, %mm5
+ pfmul %mm4, %mm2
+ pfmul %mm3, %mm1
+ pfpnacc %mm2, %mm0
+ pfmul %mm5, %mm3
+ movq 32(%edx), %mm2
+ pfpnacc %mm3, %mm1
+ movq 40(%edx), %mm3
+
+ pfadd %mm0, %mm6
+ movq 32(%eax), %mm0
+ pfadd %mm1, %mm7
+ movq 40(%eax), %mm1
+
+ addl $32, %edx
+ addl $32, %eax
+
+.L1_test:
+ decl %ecx
+ jge .loop1
+
+ # We've handled the bulk of multiplies up to here.
+ # Let's see if original n_2_ccomplex_blocks was odd.
+ # If so, we've got 2 more taps to do.
+
+ movl 16(%ebp), %ecx # n_2_ccomplex_blocks
+ andl $1, %ecx
+ je .Leven
+
+ # The count was odd, do 2 more taps.
+ # Note that we've already got mm0/mm2 & mm1/mm3 preloaded
+ # from the main loop.
+
+# A=mm0, B=mm2, Z=mm4
+# A'=mm1, B'=mm3, Z'=mm5
+
+ pswapd %mm0, %mm4
+ pfmul %mm2, %mm0
+ pswapd %mm1, %mm5
+ pfmul %mm4, %mm2
+ pfmul %mm3, %mm1
+ pfpnacc %mm2, %mm0
+ pfmul %mm5, %mm3
+ pfpnacc %mm3, %mm1
+
+ pfadd %mm0, %mm6
+ pfadd %mm1, %mm7
+
+.Leven:
+ # at this point mm6 and mm7 contain partial sums
+
+ pfadd %mm7, %mm6
+
+ movl 20(%ebp), %eax # result
+ movq %mm6, (%eax)
+
+ femms
+
+ popl %ebp
+ ret
+
+FUNC_TAIL(ccomplex_dotprod_3dnowext)
+ .ident "Hand coded x86 3DNow!Ext assembly"
+
diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext64.S b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext64.S
new file mode 100644
index 0000000000..c6f907c9ba
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext64.S
@@ -0,0 +1,188 @@
+#
+# Copyright 2002,2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_ccomplex_blocks is != 0
+#
+#
+# ccomplex_dotprod_generic (const float *input,
+# const float *taps, unsigned n_2_ccomplex_blocks, float *result)
+# {
+# float sum0 = 0;
+# float sum1 = 0;
+# float sum2 = 0;
+# float sum3 = 0;
+#
+# do {
+#
+# sum0 += input[0] * taps[0] - input[1] * taps[1];
+# sum1 += input[0] * taps[1] + input[1] * taps[0];
+# sum2 += input[2] * taps[2] - input[3] * taps[3];
+# sum3 += input[2] * taps[3] + input[3] * taps[2];
+#
+# input += 4;
+# taps += 4;
+#
+# } while (--n_2_ccomplex_blocks != 0);
+#
+#
+# result[0] = sum0 + sum2;
+# result[1] = sum1 + sum3;
+# }
+#
+
+# TODO: prefetch and better scheduling
+
+#include "assembly.h"
+
+ .file "ccomplex_dotprod_3dnowext64.S"
+ .version "01.01"
+.text
+ .p2align 4
+.globl GLOB_SYMB(ccomplex_dotprod_3dnowext)
+ DEF_FUNC_HEAD(ccomplex_dotprod_3dnowext)
+GLOB_SYMB(ccomplex_dotprod_3dnowext):
+
+ # intput: rdi, taps: rsi, n_2_ccomplex_blocks: rdx, result: rcx
+
+ mov %rdx, %rax
+
+
+ # zero accumulators
+
+ pxor %mm6, %mm6 # mm6 = 0 0
+ pxor %mm7, %mm7 # mm7 = 0 0
+
+ movq 0(%rdi), %mm0
+ movq 0(%rsi), %mm2
+
+ shr $1, %rax # rax = n_2_ccomplex_blocks / 2
+
+ movq 8(%rdi), %mm1
+ movq 8(%rsi), %mm3
+
+
+ jmp .L1_test
+
+ #
+ # 4 taps / loop
+ # something like ?? cycles / loop
+ #
+
+ .p2align 4
+.loop1:
+
+# complex prod: C += A * B, w/ temp Z
+#
+# movq 0(%rdi), %mmA
+# movq 0(%rsi), %mmB
+# pswapd %mmA, %mmZ
+# pfmul %mmB, %mmA
+# pfmul %mmZ, %mmB
+# pfpnacc %mmB, %mmA
+# pfadd %mmA, %mmC
+
+
+# A=mm0, B=mm2, Z=mm4
+# A'=mm1, B'=mm3, Z'=mm5
+
+ pswapd %mm0, %mm4
+ pfmul %mm2, %mm0
+ pswapd %mm1, %mm5
+ pfmul %mm4, %mm2
+ pfmul %mm3, %mm1
+ pfpnacc %mm2, %mm0
+ pfmul %mm5, %mm3
+ movq 16(%rsi), %mm2
+ pfpnacc %mm3, %mm1
+ movq 24(%rsi), %mm3
+
+ pfadd %mm0, %mm6
+ movq 16(%rdi), %mm0
+ pfadd %mm1, %mm7
+ movq 24(%rdi), %mm1
+
+# unroll
+
+ pswapd %mm0, %mm4
+ pfmul %mm2, %mm0
+ pswapd %mm1, %mm5
+ pfmul %mm4, %mm2
+ pfmul %mm3, %mm1
+ pfpnacc %mm2, %mm0
+ pfmul %mm5, %mm3
+ movq 32(%rsi), %mm2
+ pfpnacc %mm3, %mm1
+ movq 40(%rsi), %mm3
+
+ pfadd %mm0, %mm6
+ movq 32(%rdi), %mm0
+ pfadd %mm1, %mm7
+ movq 40(%rdi), %mm1
+
+ add $32, %rsi
+ add $32, %rdi
+
+.L1_test:
+ dec %rax
+ jge .loop1
+
+ # We've handled the bulk of multiplies up to here.
+ # Let's see if original n_2_ccomplex_blocks was odd.
+ # If so, we've got 2 more taps to do.
+
+ and $1, %rdx
+ je .Leven
+
+ # The count was odd, do 2 more taps.
+ # Note that we've already got mm0/mm2 & mm1/mm3 preloaded
+ # from the main loop.
+
+# A=mm0, B=mm2, Z=mm4
+# A'=mm1, B'=mm3, Z'=mm5
+
+ pswapd %mm0, %mm4
+ pfmul %mm2, %mm0
+ pswapd %mm1, %mm5
+ pfmul %mm4, %mm2
+ pfmul %mm3, %mm1
+ pfpnacc %mm2, %mm0
+ pfmul %mm5, %mm3
+ pfpnacc %mm3, %mm1
+
+ pfadd %mm0, %mm6
+ pfadd %mm1, %mm7
+
+.Leven:
+ # at this point mm6 and mm7 contain partial sums
+
+ pfadd %mm7, %mm6
+
+ movq %mm6, (%rcx) # result
+
+ femms
+
+ retq
+
+FUNC_TAIL(ccomplex_dotprod_3dnowext)
+ .ident "Hand coded x86_64 3DNow!Ext assembly"
+
diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_generic.cc b/gnuradio-core/src/lib/filter/ccomplex_dotprod_generic.cc
new file mode 100644
index 0000000000..edd5b1b096
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_generic.cc
@@ -0,0 +1,59 @@
+/* -*- c -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_complex.h>
+#include "gr_fir_ccc_simd.h"
+#include "ccomplex_dotprod_generic.h"
+
+#include <iostream>
+
+void
+ccomplex_dotprod_generic (const float *input,
+ const float *taps, unsigned n_2_ccomplex_blocks,
+ float *result)
+{
+ gr_complex sum0(0,0);
+ gr_complex sum1(0,0);
+
+ std::cerr << "Blah!!!\n";
+ do {
+ const gr_complex tap0(taps[0], taps[1]);
+ const gr_complex tap1(taps[2], taps[3]);
+ const gr_complex input0(input[0], input[1]);
+ const gr_complex input1(input[2], input[3]);
+
+ sum0 += input0 * tap0;
+ sum1 += input1 * tap1;
+
+ input += 8;
+ taps += 8;
+
+ } while (--n_2_ccomplex_blocks != 0);
+
+
+ sum0 += sum1;
+ result[0] = sum0.real();
+ result[1] = sum0.imag();
+}
diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_generic.h b/gnuradio-core/src/lib/filter/ccomplex_dotprod_generic.h
new file mode 100644
index 0000000000..70d3b6bda4
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_generic.h
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _CCOMPLEX_DOTPROD_GENERIC_H_
+#define _CCOMPLEX_DOTPROD_GENERIC_H_
+
+void
+ccomplex_dotprod_generic (const float *input,
+ const float *taps, unsigned n_2_ccomplex_blocks,
+ float *result);
+
+
+#endif /* _CCOMPLEX_DOTPROD_GENERIC_H_ */
diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_sse.S b/gnuradio-core/src/lib/filter/ccomplex_dotprod_sse.S
new file mode 100644
index 0000000000..a16d053537
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_sse.S
@@ -0,0 +1,194 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_ccomplex_blocks is != 0
+#
+#
+# ccomplex_dotprod_generic (const float *input,
+# const float *taps, unsigned n_2_ccomplex_blocks, float *result)
+# {
+# float sum0 = 0;
+# float sum1 = 0;
+# float sum2 = 0;
+# float sum3 = 0;
+#
+# do {
+#
+# sum0 += input[0] * taps[0] - input[1] * taps[1];
+# sum1 += input[0] * taps[1] + input[1] * taps[0];
+# sum2 += input[2] * taps[2] - input[3] * taps[3];
+# sum3 += input[2] * taps[3] + input[3] * taps[2];
+#
+# input += 4;
+# taps += 4;
+#
+# } while (--n_2_ccomplex_blocks != 0);
+#
+#
+# result[0] = sum0 + sum2;
+# result[1] = sum1 + sum3;
+# }
+#
+
+# TODO: prefetch and better scheduling
+
+#include "assembly.h"
+
+ .file "ccomplex_dotprod_sse.S"
+ .version "01.01"
+.text
+ .p2align 4
+.globl GLOB_SYMB(ccomplex_dotprod_sse)
+ DEF_FUNC_HEAD(ccomplex_dotprod_sse)
+GLOB_SYMB(ccomplex_dotprod_sse):
+ pushl %ebp
+ movl %esp, %ebp
+ movl 8(%ebp), %eax # input
+ movl 12(%ebp), %edx # taps
+ movl 16(%ebp), %ecx # n_2_ccomplex_blocks
+
+ xorps %xmm6, %xmm6 # zero accumulators
+
+ movaps 0(%eax), %xmm0
+
+ xorps %xmm7, %xmm7 # zero accumulators
+
+ movaps 0(%edx), %xmm2
+
+ shrl $1, %ecx # ecx = n_2_ccomplex_blocks / 2
+
+ jmp .L1_test
+
+ #
+ # 4 taps / loop
+ # something like ?? cycles / loop
+ #
+
+ .p2align 4
+.loop1:
+
+# complex prod: C += A * B, w/ temp Z & Y (or B), xmmPN=$0x8000000080000000
+#
+# movaps (%eax), %xmmA
+# movaps (%edx), %xmmB
+#
+# movaps %xmmA, %xmmZ
+# shufps $0xb1, %xmmZ, %xmmZ # swap internals
+#
+# mulps %xmmB, %xmmA
+# mulps %xmmZ, %xmmB
+#
+# # SSE replacement for: pfpnacc %xmmB, %xmmA
+# xorps %xmmPN, %xmmA
+# movaps %xmmA, %xmmZ
+# unpcklps %xmmB, %xmmA
+# unpckhps %xmmB, %xmmZ
+# movaps %xmmZ, %xmmY
+# shufps $0x44, %xmmA, %xmmZ # b01000100
+# shufps $0xee, %xmmY, %xmmA # b11101110
+# addps %xmmZ, %xmmA
+#
+# addps %xmmA, %xmmC
+
+# A=xmm0, B=xmm2, Z=xmm4
+# A'=xmm1, B'=xmm3, Z'=xmm5
+
+ movaps 16(%eax), %xmm1
+
+ movaps %xmm0, %xmm4
+ mulps %xmm2, %xmm0
+
+ shufps $0xb1, %xmm4, %xmm4 # swap internals
+ movaps 16(%edx), %xmm3
+ movaps %xmm1, %xmm5
+ addps %xmm0, %xmm6
+ mulps %xmm3, %xmm1
+ shufps $0xb1, %xmm5, %xmm5 # swap internals
+ addps %xmm1, %xmm6
+ mulps %xmm4, %xmm2
+ movaps 32(%eax), %xmm0
+ addps %xmm2, %xmm7
+ mulps %xmm5, %xmm3
+
+ addl $32, %eax
+
+ movaps 32(%edx), %xmm2
+ addps %xmm3, %xmm7
+
+ addl $32, %edx
+
+
+
+.L1_test:
+ decl %ecx
+ jge .loop1
+
+ # We've handled the bulk of multiplies up to here.
+ # Let's sse if original n_2_ccomplex_blocks was odd.
+ # If so, we've got 2 more taps to do.
+
+ movl 16(%ebp), %ecx # n_2_ccomplex_blocks
+ andl $1, %ecx
+ je .Leven
+
+ # The count was odd, do 2 more taps.
+ # Note that we've already got mm0/mm2 preloaded
+ # from the main loop.
+
+ movaps %xmm0, %xmm4
+ mulps %xmm2, %xmm0
+ shufps $0xb1, %xmm4, %xmm4 # swap internals
+ addps %xmm0, %xmm6
+ mulps %xmm4, %xmm2
+ addps %xmm2, %xmm7
+
+
+.Leven:
+ # neg inversor
+ xorps %xmm1, %xmm1
+ movl $0x80000000, 16(%ebp)
+ movss 16(%ebp), %xmm1
+ shufps $0x11, %xmm1, %xmm1 # b00010001 # 0 -0 0 -0
+
+ # pfpnacc
+ xorps %xmm1, %xmm6
+
+ movaps %xmm6, %xmm2
+ unpcklps %xmm7, %xmm6
+ unpckhps %xmm7, %xmm2
+ movaps %xmm2, %xmm3
+ shufps $0x44, %xmm6, %xmm2 # b01000100
+ shufps $0xee, %xmm3, %xmm6 # b11101110
+ addps %xmm2, %xmm6
+
+ # xmm6 = r1 i2 r3 i4
+ movl 20(%ebp), %eax # @result
+ movhlps %xmm6, %xmm4 # xmm4 = r3 i4 ?? ??
+ addps %xmm4, %xmm6 # xmm6 = r1+r3 i2+i4 ?? ??
+ movlps %xmm6, (%eax) # store low 2x32 bits (complex) to memory
+
+ popl %ebp
+ ret
+
+FUNC_TAIL(ccomplex_dotprod_sse)
+ .ident "Hand coded x86 SSE assembly"
diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_sse64.S b/gnuradio-core/src/lib/filter/ccomplex_dotprod_sse64.S
new file mode 100644
index 0000000000..216df6e526
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_sse64.S
@@ -0,0 +1,191 @@
+#
+# Copyright 2002,2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_ccomplex_blocks is != 0
+#
+#
+# ccomplex_dotprod_generic (const float *input,
+# const float *taps, unsigned n_2_ccomplex_blocks, float *result)
+# {
+# float sum0 = 0;
+# float sum1 = 0;
+# float sum2 = 0;
+# float sum3 = 0;
+#
+# do {
+#
+# sum0 += input[0] * taps[0] - input[1] * taps[1];
+# sum1 += input[0] * taps[1] + input[1] * taps[0];
+# sum2 += input[2] * taps[2] - input[3] * taps[3];
+# sum3 += input[2] * taps[3] + input[3] * taps[2];
+#
+# input += 4;
+# taps += 4;
+#
+# } while (--n_2_ccomplex_blocks != 0);
+#
+#
+# result[0] = sum0 + sum2;
+# result[1] = sum1 + sum3;
+# }
+#
+
+# TODO: prefetch and better scheduling
+
+#include "assembly.h"
+
+
+ .file "ccomplex_dotprod_sse64.S"
+ .version "01.01"
+.text
+ .p2align 4
+.globl GLOB_SYMB(ccomplex_dotprod_sse)
+ DEF_FUNC_HEAD(ccomplex_dotprod_sse)
+GLOB_SYMB(ccomplex_dotprod_sse):
+
+ # intput: rdi, taps: rsi, n_2_ccomplex_blocks: rdx, result: rcx
+
+ mov %rdx, %rax
+
+ xorps %xmm6, %xmm6 # zero accumulators
+
+ movaps 0(%rdi), %xmm0
+
+ xorps %xmm7, %xmm7 # zero accumulators
+
+ movaps 0(%rsi), %xmm2
+
+ shr $1, %rax # rax = n_2_ccomplex_blocks / 2
+
+ jmp .L1_test
+
+ #
+ # 4 taps / loop
+ # something like ?? cycles / loop
+ #
+
+ .p2align 4
+.loop1:
+
+# complex prod: C += A * B, w/ temp Z & Y (or B), xmmPN=$0x8000000080000000
+#
+# movaps (%rdi), %xmmA
+# movaps (%rsi), %xmmB
+#
+# movaps %xmmA, %xmmZ
+# shufps $0xb1, %xmmZ, %xmmZ # swap internals
+#
+# mulps %xmmB, %xmmA
+# mulps %xmmZ, %xmmB
+#
+# # SSE replacement for: pfpnacc %xmmB, %xmmA
+# xorps %xmmPN, %xmmA
+# movaps %xmmA, %xmmZ
+# unpcklps %xmmB, %xmmA
+# unpckhps %xmmB, %xmmZ
+# movaps %xmmZ, %xmmY
+# shufps $0x44, %xmmA, %xmmZ # b01000100
+# shufps $0xee, %xmmY, %xmmA # b11101110
+# addps %xmmZ, %xmmA
+#
+# addps %xmmA, %xmmC
+
+# A=xmm0, B=xmm2, Z=xmm4
+# A'=xmm1, B'=xmm3, Z'=xmm5
+
+ movaps 16(%rdi), %xmm1
+
+ movaps %xmm0, %xmm4
+ mulps %xmm2, %xmm0
+
+ shufps $0xb1, %xmm4, %xmm4 # swap internals
+ movaps 16(%rsi), %xmm3
+ movaps %xmm1, %xmm5
+ addps %xmm0, %xmm6
+ mulps %xmm3, %xmm1
+ shufps $0xb1, %xmm5, %xmm5 # swap internals
+ addps %xmm1, %xmm6
+ mulps %xmm4, %xmm2
+ movaps 32(%rdi), %xmm0
+ addps %xmm2, %xmm7
+ mulps %xmm5, %xmm3
+
+ add $32, %rdi
+
+ movaps 32(%rsi), %xmm2
+ addps %xmm3, %xmm7
+
+ add $32, %rsi
+
+
+
+.L1_test:
+ dec %rax
+ jge .loop1
+
+ # We've handled the bulk of multiplies up to here.
+ # Let's sse if original n_2_ccomplex_blocks was odd.
+ # If so, we've got 2 more taps to do.
+
+ and $1, %rdx
+ je .Leven
+
+ # The count was odd, do 2 more taps.
+ # Note that we've already got mm0/mm2 preloaded
+ # from the main loop.
+
+ movaps %xmm0, %xmm4
+ mulps %xmm2, %xmm0
+ shufps $0xb1, %xmm4, %xmm4 # swap internals
+ addps %xmm0, %xmm6
+ mulps %xmm4, %xmm2
+ addps %xmm2, %xmm7
+
+
+.Leven:
+ # neg inversor
+ xorps %xmm1, %xmm1
+ movl $0x80000000, -8(%rsp)
+ movss -8(%rsp), %xmm1
+ shufps $0x11, %xmm1, %xmm1 # b00010001 # 0 -0 0 -0
+
+ # pfpnacc
+ xorps %xmm1, %xmm6
+
+ movaps %xmm6, %xmm2
+ unpcklps %xmm7, %xmm6
+ unpckhps %xmm7, %xmm2
+ movaps %xmm2, %xmm3
+ shufps $0x44, %xmm6, %xmm2 # b01000100
+ shufps $0xee, %xmm3, %xmm6 # b11101110
+ addps %xmm2, %xmm6
+
+ # xmm6 = r1 i2 r3 i4
+ movhlps %xmm6, %xmm4 # xmm4 = r3 i4 ?? ??
+ addps %xmm4, %xmm6 # xmm6 = r1+r3 i2+i4 ?? ??
+ movlps %xmm6, (%rcx) # store low 2x32 bits (complex) to memory
+
+ retq
+
+FUNC_TAIL(ccomplex_dotprod_sse)
+ .ident "Hand coded x86_64 SSE assembly"
diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_x86.h b/gnuradio-core/src/lib/filter/ccomplex_dotprod_x86.h
new file mode 100644
index 0000000000..0a8c73633f
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _CCOMPLEX_DOTPROD_X86_H_
+#define _CCOMPLEX_DOTPROD_X86_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void
+ccomplex_dotprod_3dnow (const float *input,
+ const float *taps, unsigned n_2_ccomplex_blocks, float *result);
+
+void
+ccomplex_dotprod_3dnowext (const float *input,
+ const float *taps, unsigned n_2_ccomplex_blocks, float *result);
+
+void
+ccomplex_dotprod_sse (const float *input,
+ const float *taps, unsigned n_2_ccomplex_blocks, float *result);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CCOMPLEX_DOTPROD_X86_H_ */
diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_3dnow.S b/gnuradio-core/src/lib/filter/complex_dotprod_3dnow.S
new file mode 100644
index 0000000000..37608ece1b
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/complex_dotprod_3dnow.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 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_complex_blocks is != 0
+#
+#
+# complex_dotprod_generic (const short *input,
+# const float *taps, unsigned n_2_complex_blocks, float *result)
+# {
+# float sum0 = 0;
+# float sum1 = 0;
+# float sum2 = 0;
+# float sum3 = 0;
+#
+# do {
+#
+# sum0 += input[0] * taps[0];
+# sum1 += input[0] * taps[1];
+# sum2 += input[1] * taps[2];
+# sum3 += input[1] * taps[3];
+#
+# input += 2;
+# taps += 4;
+#
+# } while (--n_2_complex_blocks != 0);
+#
+#
+# result[0] = sum0 + sum2;
+# result[1] = sum1 + sum3;
+# }
+#
+
+#include "assembly.h"
+
+ .file "complex_dotprod_3dnow.S"
+ .version "01.01"
+.text
+ .p2align 4
+.globl GLOB_SYMB(complex_dotprod_3dnow)
+ DEF_FUNC_HEAD(complex_dotprod_3dnow)
+GLOB_SYMB(complex_dotprod_3dnow):
+ pushl %ebp
+ movl %esp, %ebp
+ movl 8(%ebp), %eax # input
+ movl 12(%ebp), %edx # taps
+ movl 16(%ebp), %ecx
+
+ # zero accumulators
+
+ pxor %mm4, %mm4 # mm4 = 0 0
+ pxor %mm5, %mm5 # mm5 = 0 0
+ pxor %mm6, %mm6 # mm6 = 0 0
+ pxor %mm7, %mm7 # mm7 = 0 0
+
+
+ shrl $1, %ecx # ecx = n_2_complex_blocks / 2
+
+ # pshufw & pi2fw
+ pxor %mm0, %mm0
+ punpcklwd 0(%eax), %mm0
+ psrad $16, %mm0
+ punpckldq %mm0, %mm0
+ pi2fd %mm0, %mm0
+
+ pxor %mm1, %mm1
+ punpcklwd 0(%eax), %mm1
+ psrad $16, %mm1
+ punpckhdq %mm1, %mm1
+ pi2fd %mm1, %mm1
+
+ pxor %mm2, %mm2
+ pxor %mm3, %mm3
+
+
+ jmp .L1_test
+
+ #
+ # 4 taps / loop
+ # something like ?? cycles / loop
+ #
+
+ .p2align 4
+.loop1:
+ pfmul 0(%edx), %mm0
+ pfadd %mm2, %mm6
+
+ pxor %mm2, %mm2
+ punpcklwd 4(%eax), %mm2
+ psrad $16, %mm2
+ punpckldq %mm2, %mm2
+
+ pfmul 8(%edx), %mm1
+ pfadd %mm3, %mm7
+ pi2fd %mm2, %mm2
+
+ pxor %mm3, %mm3
+ punpcklwd 4(%eax), %mm3
+ psrad $16, %mm3
+ punpckhdq %mm3, %mm3
+
+ pfmul 16(%edx), %mm2
+ pfadd %mm0, %mm4
+ pi2fd %mm3, %mm3
+
+ pxor %mm0, %mm0
+ punpcklwd 8(%eax), %mm0
+ psrad $16, %mm0
+ punpckldq %mm0, %mm0
+
+ pfmul 24(%edx), %mm3
+ pfadd %mm1, %mm5
+
+ pxor %mm1, %mm1
+ punpcklwd 8(%eax), %mm1
+ psrad $16, %mm1
+ punpckhdq %mm1, %mm1
+
+ pi2fd %mm0, %mm0
+ pi2fd %mm1, %mm1
+
+#TODO: add prefetch
+
+ addl $32, %edx
+ addl $8, %eax
+
+.L1_test:
+ decl %ecx
+ jge .loop1
+
+ # We've handled the bulk of multiplies up to here.
+ # Now accumulate the final two additions and see if original
+ # n_2_complex_blocks was odd. If so, we've got 2 more
+ # taps to do.
+
+ movl 16(%ebp), %ecx
+ pfadd %mm2, %mm6
+ andl $1, %ecx
+ pfadd %mm3, %mm7
+ je .Leven
+
+ # The count was odd, do 2 more taps.
+ # Note that we've already got mm0 and mm1 preloaded
+ # from the main loop.
+
+ pfmul 0(%edx), %mm0
+ pfadd %mm0, %mm4
+ pfmul 8(%edx), %mm1
+ pfadd %mm1, %mm5
+
+.Leven:
+ # at this point mm4, mm5, mm6 and mm7 contain partial sums
+
+ pfadd %mm7, %mm6
+ pfadd %mm5, %mm4
+
+ movl 20(%ebp), %eax # result
+
+ pfadd %mm6, %mm4
+
+ movq %mm4, (%eax)
+ femms
+
+ popl %ebp
+ ret
+
+FUNC_TAIL(complex_dotprod_3dnow)
+ .ident "Hand coded x86 3DNow! assembly"
+
diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_3dnow64.S b/gnuradio-core/src/lib/filter/complex_dotprod_3dnow64.S
new file mode 100644
index 0000000000..1413c6ceba
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/complex_dotprod_3dnow64.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 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_complex_blocks is != 0
+#
+#
+# complex_dotprod_generic (const short *input,
+# const float *taps, unsigned n_2_complex_blocks, float *result)
+# {
+# float sum0 = 0;
+# float sum1 = 0;
+# float sum2 = 0;
+# float sum3 = 0;
+#
+# do {
+#
+# sum0 += input[0] * taps[0];
+# sum1 += input[0] * taps[1];
+# sum2 += input[1] * taps[2];
+# sum3 += input[1] * taps[3];
+#
+# input += 2;
+# taps += 4;
+#
+# } while (--n_2_complex_blocks != 0);
+#
+#
+# result[0] = sum0 + sum2;
+# result[1] = sum1 + sum3;
+# }
+#
+
+#include "assembly.h"
+
+
+ .file "complex_dotprod_3dnow64.S"
+ .version "01.01"
+.text
+ .p2align 4
+.globl GLOB_SYMB(complex_dotprod_3dnow)
+ DEF_FUNC_HEAD(complex_dotprod_3dnow)
+GLOB_SYMB(complex_dotprod_3dnow):
+
+ # intput: rdi, taps: rsi, n_2_ccomplex_blocks: rdx, result: rcx
+
+ mov %rdx, %rax
+
+ # zero accumulators
+
+ pxor %mm4, %mm4 # mm4 = 0 0
+ pxor %mm5, %mm5 # mm5 = 0 0
+ pxor %mm6, %mm6 # mm6 = 0 0
+ pxor %mm7, %mm7 # mm7 = 0 0
+
+
+ shr $1, %rax # rax = n_2_complex_blocks / 2
+
+ # pshufw & pi2fw
+ pxor %mm0, %mm0
+ punpcklwd 0(%rdi), %mm0
+ psrad $16, %mm0
+ punpckldq %mm0, %mm0
+ pi2fd %mm0, %mm0
+
+ pxor %mm1, %mm1
+ punpcklwd 0(%rdi), %mm1
+ psrad $16, %mm1
+ punpckhdq %mm1, %mm1
+ pi2fd %mm1, %mm1
+
+ pxor %mm2, %mm2
+ pxor %mm3, %mm3
+
+
+ jmp .L1_test
+
+ #
+ # 4 taps / loop
+ # something like ?? cycles / loop
+ #
+
+ .p2align 4
+.loop1:
+ pfmul 0(%rsi), %mm0
+ pfadd %mm2, %mm6
+
+ pxor %mm2, %mm2
+ punpcklwd 4(%rdi), %mm2
+ psrad $16, %mm2
+ punpckldq %mm2, %mm2
+
+ pfmul 8(%rsi), %mm1
+ pfadd %mm3, %mm7
+ pi2fd %mm2, %mm2
+
+ pxor %mm3, %mm3
+ punpcklwd 4(%rdi), %mm3
+ psrad $16, %mm3
+ punpckhdq %mm3, %mm3
+
+ pfmul 16(%rsi), %mm2
+ pfadd %mm0, %mm4
+ pi2fd %mm3, %mm3
+
+ pxor %mm0, %mm0
+ punpcklwd 8(%rdi), %mm0
+ psrad $16, %mm0
+ punpckldq %mm0, %mm0
+
+ pfmul 24(%rsi), %mm3
+ pfadd %mm1, %mm5
+
+ pxor %mm1, %mm1
+ punpcklwd 8(%rdi), %mm1
+ psrad $16, %mm1
+ punpckhdq %mm1, %mm1
+
+ pi2fd %mm0, %mm0
+ pi2fd %mm1, %mm1
+
+#TODO: add prefetch
+
+ add $32, %rsi
+ add $8, %rdi
+
+.L1_test:
+ dec %rax
+ jge .loop1
+
+ # We've handled the bulk of multiplies up to here.
+ # Now accumulate the final two additions and see if original
+ # n_2_complex_blocks was odd. If so, we've got 2 more
+ # taps to do.
+
+ pfadd %mm2, %mm6
+ and $1, %rdx
+ pfadd %mm3, %mm7
+ je .Leven
+
+ # The count was odd, do 2 more taps.
+ # Note that we've already got mm0 and mm1 preloaded
+ # from the main loop.
+
+ pfmul 0(%rsi), %mm0
+ pfadd %mm0, %mm4
+ pfmul 8(%rsi), %mm1
+ pfadd %mm1, %mm5
+
+.Leven:
+ # at this point mm4, mm5, mm6 and mm7 contain partial sums
+
+ pfadd %mm7, %mm6
+ pfadd %mm5, %mm4
+ pfadd %mm6, %mm4
+
+ movq %mm4, (%rcx)
+ femms
+
+ retq
+
+FUNC_TAIL(complex_dotprod_3dnow)
+ .ident "Hand coded x86_64 3DNow! assembly"
+
diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_3dnowext.S b/gnuradio-core/src/lib/filter/complex_dotprod_3dnowext.S
new file mode 100644
index 0000000000..443949ed2e
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/complex_dotprod_3dnowext.S
@@ -0,0 +1,167 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_complex_blocks is != 0
+#
+#
+# complex_dotprod_generic (const short *input,
+# const float *taps, unsigned n_2_complex_blocks, float *result)
+# {
+# float sum0 = 0;
+# float sum1 = 0;
+# float sum2 = 0;
+# float sum3 = 0;
+#
+# do {
+#
+# sum0 += input[0] * taps[0];
+# sum1 += input[0] * taps[1];
+# sum2 += input[1] * taps[2];
+# sum3 += input[1] * taps[3];
+#
+# input += 2;
+# taps += 4;
+#
+# } while (--n_2_complex_blocks != 0);
+#
+#
+# result[0] = sum0 + sum2;
+# result[1] = sum1 + sum3;
+# }
+#
+
+#include "assembly.h"
+
+ .file "complex_dotprod_3dnowext.S"
+ .version "01.01"
+.text
+ .p2align 4
+.globl GLOB_SYMB(complex_dotprod_3dnowext)
+ DEF_FUNC_HEAD(complex_dotprod_3dnowext)
+GLOB_SYMB(complex_dotprod_3dnowext):
+ pushl %ebp
+ movl %esp, %ebp
+ movl 8(%ebp), %eax # input
+ movl 12(%ebp), %edx # taps
+ movl 16(%ebp), %ecx
+
+ # zero accumulators
+
+ pxor %mm4, %mm4 # mm4 = 0 0
+ pxor %mm5, %mm5 # mm5 = 0 0
+ pxor %mm6, %mm6 # mm6 = 0 0
+ pxor %mm7, %mm7 # mm7 = 0 0
+
+
+ shrl $1, %ecx # ecx = n_2_complex_blocks / 2
+
+ movd 0(%eax), %mm0
+ pshufw $0x55, %mm0, %mm1 # b01010101
+ pshufw $0, %mm0, %mm0
+
+ pxor %mm2, %mm2
+ pxor %mm3, %mm3
+
+ pi2fw %mm1, %mm1
+ pi2fw %mm0, %mm0
+
+ jmp .L1_test
+
+ #
+ # 4 taps / loop
+ # something like ?? cycles / loop
+ #
+
+ .p2align 4
+.loop1:
+ pfmul 0(%edx), %mm0
+ pfadd %mm2, %mm6
+
+ pshufw $0, 4(%eax), %mm2
+
+ pfmul 8(%edx), %mm1
+ pfadd %mm3, %mm7
+ pi2fw %mm2, %mm2
+
+ pshufw $0x55, 4(%eax), %mm3 # b01010101
+
+ pfmul 16(%edx), %mm2
+ pi2fw %mm3, %mm3
+ pfadd %mm0, %mm4
+
+ pshufw $0, 8(%eax), %mm0
+
+ pfmul 24(%edx), %mm3
+ pfadd %mm1, %mm5
+
+ pshufw $0x55, 8(%eax), %mm1 # b01010101
+ pi2fw %mm0, %mm0
+
+#TODO: add prefetch
+
+ addl $32, %edx
+ addl $8, %eax
+ pi2fw %mm1, %mm1
+
+.L1_test:
+ decl %ecx
+ jge .loop1
+
+ # We've handled the bulk of multiplies up to here.
+ # Now accumulate the final two additions and see if original
+ # n_2_complex_blocks was odd. If so, we've got 2 more
+ # taps to do.
+
+ movl 16(%ebp), %ecx
+ pfadd %mm2, %mm6
+ andl $1, %ecx
+ pfadd %mm3, %mm7
+ je .Leven
+
+ # The count was odd, do 2 more taps.
+ # Note that we've already got mm0 and mm1 preloaded
+ # from the main loop.
+
+ pfmul 0(%edx), %mm0
+ pfadd %mm0, %mm4
+ pfmul 8(%edx), %mm1
+ pfadd %mm1, %mm5
+
+.Leven:
+ # at this point mm4, mm5, mm6 and mm7 contain partial sums
+
+ pfadd %mm7, %mm6
+ pfadd %mm5, %mm4
+
+ movl 20(%ebp), %eax # result
+ pfadd %mm6, %mm4
+ movq %mm4, (%eax)
+
+ femms
+
+ popl %ebp
+ ret
+
+FUNC_TAIL(complex_dotprod_3dnowext)
+ .ident "Hand coded x86 3DNow!Ext assembly"
+
diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_3dnowext64.S b/gnuradio-core/src/lib/filter/complex_dotprod_3dnowext64.S
new file mode 100644
index 0000000000..195dc37761
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/complex_dotprod_3dnowext64.S
@@ -0,0 +1,164 @@
+#
+# Copyright 2002,2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_complex_blocks is != 0
+#
+#
+# complex_dotprod_generic (const short *input,
+# const float *taps, unsigned n_2_complex_blocks, float *result)
+# {
+# float sum0 = 0;
+# float sum1 = 0;
+# float sum2 = 0;
+# float sum3 = 0;
+#
+# do {
+#
+# sum0 += input[0] * taps[0];
+# sum1 += input[0] * taps[1];
+# sum2 += input[1] * taps[2];
+# sum3 += input[1] * taps[3];
+#
+# input += 2;
+# taps += 4;
+#
+# } while (--n_2_complex_blocks != 0);
+#
+#
+# result[0] = sum0 + sum2;
+# result[1] = sum1 + sum3;
+# }
+#
+
+#include "assembly.h"
+
+
+ .file "complex_dotprod_3dnowext64.S"
+ .version "01.01"
+.text
+ .p2align 4
+.globl GLOB_SYMB(complex_dotprod_3dnowext)
+ DEF_FUNC_HEAD(complex_dotprod_3dnowext)
+GLOB_SYMB(complex_dotprod_3dnowext):
+
+ # intput: rdi, taps: rsi, n_2_ccomplex_blocks: rdx, result: rcx
+
+ mov %rdx, %rax
+
+ # zero accumulators
+
+ pxor %mm4, %mm4 # mm4 = 0 0
+ pxor %mm5, %mm5 # mm5 = 0 0
+ pxor %mm6, %mm6 # mm6 = 0 0
+ pxor %mm7, %mm7 # mm7 = 0 0
+
+
+ shr $1, %rax # rax = n_2_complex_blocks / 2
+
+ movd 0(%rdi), %mm0
+ pshufw $0x55, %mm0, %mm1 # b01010101
+ pshufw $0, %mm0, %mm0
+
+ pxor %mm2, %mm2
+ pxor %mm3, %mm3
+
+ pi2fw %mm1, %mm1
+ pi2fw %mm0, %mm0
+
+ jmp .L1_test
+
+ #
+ # 4 taps / loop
+ # something like ?? cycles / loop
+ #
+
+ .p2align 4
+.loop1:
+ pfmul 0(%rsi), %mm0
+ pfadd %mm2, %mm6
+
+ pshufw $0, 4(%rdi), %mm2
+
+ pfmul 8(%rsi), %mm1
+ pfadd %mm3, %mm7
+ pi2fw %mm2, %mm2
+
+ pshufw $0x55, 4(%rdi), %mm3 # b01010101
+
+ pfmul 16(%rsi), %mm2
+ pi2fw %mm3, %mm3
+ pfadd %mm0, %mm4
+
+ pshufw $0, 8(%rdi), %mm0
+
+ pfmul 24(%rsi), %mm3
+ pfadd %mm1, %mm5
+
+ pshufw $0x55, 8(%rdi), %mm1 # b01010101
+ pi2fw %mm0, %mm0
+
+#TODO: add prefetch
+
+ add $32, %rsi
+ add $8, %rdi
+ pi2fw %mm1, %mm1
+
+.L1_test:
+ dec %rax
+ jge .loop1
+
+ # We've handled the bulk of multiplies up to here.
+ # Now accumulate the final two additions and see if original
+ # n_2_complex_blocks was odd. If so, we've got 2 more
+ # taps to do.
+
+ pfadd %mm2, %mm6
+ and $1, %rdx
+ pfadd %mm3, %mm7
+ je .Leven
+
+ # The count was odd, do 2 more taps.
+ # Note that we've already got mm0 and mm1 preloaded
+ # from the main loop.
+
+ pfmul 0(%rsi), %mm0
+ pfadd %mm0, %mm4
+ pfmul 8(%rsi), %mm1
+ pfadd %mm1, %mm5
+
+.Leven:
+ # at this point mm4, mm5, mm6 and mm7 contain partial sums
+
+ pfadd %mm7, %mm6
+ pfadd %mm5, %mm4
+
+ pfadd %mm6, %mm4
+ movq %mm4, (%rcx)
+
+ femms
+
+ retq
+
+FUNC_TAIL(complex_dotprod_3dnowext)
+ .ident "Hand coded x86_64 3DNow!Ext assembly"
+
diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_generic.cc b/gnuradio-core/src/lib/filter/complex_dotprod_generic.cc
new file mode 100644
index 0000000000..300f4700f1
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/complex_dotprod_generic.cc
@@ -0,0 +1,55 @@
+/* -*- c -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_complex.h>
+#include "gr_fir_scc_simd.h"
+#include "complex_dotprod_generic.h"
+
+
+void
+complex_dotprod_generic (const short *input,
+ const float *taps, unsigned n_2_complex_blocks,
+ float *result)
+{
+ gr_complex sum0(0,0);
+ gr_complex sum1(0,0);
+
+ do {
+ const gr_complex tap0(taps[0], taps[1]);
+ const gr_complex tap1(taps[2], taps[3]);
+
+ sum0 += (float)input[0] * tap0;
+ sum1 += (float)input[1] * tap1;
+
+ input += 4;
+ taps += 8;
+
+ } while (--n_2_complex_blocks != 0);
+
+
+ sum0 += sum1;
+ result[0] = sum0.real();
+ result[1] = sum0.imag();
+}
diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_generic.h b/gnuradio-core/src/lib/filter/complex_dotprod_generic.h
new file mode 100644
index 0000000000..44a4ea55f1
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/complex_dotprod_generic.h
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _COMPLEX_DOTPROD_GENERIC_H_
+#define _COMPLEX_DOTPROD_GENERIC_H_
+
+void
+complex_dotprod_generic (const short *input,
+ const float *taps, unsigned n_2_complex_blocks,
+ float *result);
+
+
+#endif /* _COMPLEX_DOTPROD_GENERIC_H_ */
diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_sse.S b/gnuradio-core/src/lib/filter/complex_dotprod_sse.S
new file mode 100644
index 0000000000..acafb1a31f
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/complex_dotprod_sse.S
@@ -0,0 +1,202 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_complex_blocks is != 0
+#
+#
+# complex_dotprod_generic (const short *input,
+# const float *taps, unsigned n_2_complex_blocks, float *result)
+# {
+# float sum0 = 0;
+# float sum1 = 0;
+# float sum2 = 0;
+# float sum3 = 0;
+#
+# do {
+#
+# sum0 += input[0] * taps[0];
+# sum1 += input[0] * taps[1];
+# sum2 += input[1] * taps[2];
+# sum3 += input[1] * taps[3];
+#
+# input += 2;
+# taps += 4;
+#
+# } while (--n_2_complex_blocks != 0);
+#
+#
+# result[0] = sum0 + sum2;
+# result[1] = sum1 + sum3;
+# }
+#
+
+# TODO: prefetch and better scheduling
+
+#include "assembly.h"
+
+
+ .file "complex_dotprod_sse.S"
+ .version "01.01"
+.text
+ .p2align 4
+.globl GLOB_SYMB(complex_dotprod_sse)
+ DEF_FUNC_HEAD(complex_dotprod_sse)
+GLOB_SYMB(complex_dotprod_sse):
+ pushl %ebp
+ movl %esp, %ebp
+ movl 8(%ebp), %eax # input
+ movl 12(%ebp), %edx # taps
+ movl 16(%ebp), %ecx
+
+
+ # xmm0 xmm1 xmm2 xmm3 are used to hold taps and the result of mults
+ # xmm4 xmm5 xmm6 xmm7 are used to hold the accumulated results
+
+ xorps %xmm4, %xmm4 # zero two accumulators
+ xorps %xmm5, %xmm5 # xmm5 holds zero for use below
+
+ # first handle any non-zero remainder of (n_2_complex_blocks % 4)
+
+ andl $0x3, %ecx
+ jmp .L1_test
+
+ .p2align 4
+.loop1:
+
+ pxor %mm0, %mm0
+ punpcklwd 0(%eax), %mm0
+ psrad $16, %mm0
+ cvtpi2ps %mm0, %xmm0
+ shufps $0x50, %xmm0, %xmm0
+
+ mulps (%edx), %xmm0
+ addl $0x10, %edx
+ addl $4, %eax
+ addps %xmm0, %xmm4
+.L1_test:
+ decl %ecx
+ jge .loop1
+
+
+ # set up for primary loop which is unrolled 4 times
+
+ movl 16(%ebp), %ecx
+ movaps %xmm5, %xmm6 # zero remaining accumulators
+ movaps %xmm5, %xmm7
+
+ shrl $2, %ecx # n_2_complex_blocks / 4
+ je .cleanup # if zero, take short path
+
+ # finish setup and loop priming
+
+ pxor %mm0, %mm0
+ punpcklwd 0(%eax), %mm0
+ psrad $16, %mm0
+ cvtpi2ps %mm0, %xmm0
+ shufps $0x50, %xmm0, %xmm0
+
+ movaps %xmm5, %xmm2
+
+ pxor %mm1, %mm1
+ punpcklwd 4(%eax), %mm1
+ psrad $16, %mm1
+ cvtpi2ps %mm1, %xmm1
+ shufps $0x50, %xmm1, %xmm1
+
+ movaps %xmm5, %xmm3
+
+ # we know ecx is not zero, we checked above,
+ # hence enter loop at top
+
+ .p2align 4
+.loop2:
+ mulps (%edx), %xmm0
+ addps %xmm2, %xmm6
+
+ pxor %mm2, %mm2
+ punpcklwd 8(%eax), %mm2
+ psrad $16, %mm2
+ cvtpi2ps %mm2, %xmm2
+ shufps $0x50, %xmm2, %xmm2
+
+ mulps 0x10(%edx), %xmm1
+ addps %xmm3, %xmm7
+
+ pxor %mm3, %mm3
+ punpcklwd 12(%eax), %mm3
+ psrad $16, %mm3
+ cvtpi2ps %mm3, %xmm3
+ shufps $0x50, %xmm3, %xmm3
+
+ mulps 0x20(%edx), %xmm2
+ addps %xmm0, %xmm4
+
+ pxor %mm0, %mm0
+ punpcklwd 16(%eax), %mm0
+ psrad $16, %mm0
+ cvtpi2ps %mm0, %xmm0
+ shufps $0x50, %xmm0, %xmm0
+
+ mulps 0x30(%edx), %xmm3
+ addps %xmm1, %xmm5
+
+ pxor %mm1, %mm1
+ punpcklwd 20(%eax), %mm1
+ psrad $16, %mm1
+ cvtpi2ps %mm1, %xmm1
+ shufps $0x50, %xmm1, %xmm1
+
+ addl $0x40, %edx
+ addl $0x10, %eax
+ decl %ecx
+ jne .loop2
+
+ # OK, now we've done with all the multiplies, but
+ # we still need to handle the unaccumulated
+ # products in xmm2 and xmm3
+
+ addps %xmm2, %xmm6
+ addps %xmm3, %xmm7
+
+ # now we want to add all accumulators into xmm4
+
+ addps %xmm5, %xmm4
+ addps %xmm6, %xmm7
+ addps %xmm7, %xmm4
+
+
+ # At this point, xmm4 contains 2x2 partial sums. We need
+ # to compute a "horizontal complex add" across xmm4.
+
+.cleanup: # xmm4 = r1 i2 r3 i4
+ movl 20(%ebp), %eax # @result
+ movhlps %xmm4, %xmm0 # xmm0 = ?? ?? r1 r2
+ addps %xmm4, %xmm0 # xmm0 = ?? ?? r1+r3 i2+i4
+ movlps %xmm0, (%eax) # store low 2x32 bits (complex) to memory
+
+ emms
+ popl %ebp
+ ret
+
+FUNC_TAIL(complex_dotprod_sse)
+ .ident "Hand coded x86 SSE assembly"
diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_sse64.S b/gnuradio-core/src/lib/filter/complex_dotprod_sse64.S
new file mode 100644
index 0000000000..0fb95db003
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/complex_dotprod_sse64.S
@@ -0,0 +1,198 @@
+#
+# Copyright 2002,2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_complex_blocks is != 0
+#
+#
+# complex_dotprod_generic (const short *input,
+# const float *taps, unsigned n_2_complex_blocks, float *result)
+# {
+# float sum0 = 0;
+# float sum1 = 0;
+# float sum2 = 0;
+# float sum3 = 0;
+#
+# do {
+#
+# sum0 += input[0] * taps[0];
+# sum1 += input[0] * taps[1];
+# sum2 += input[1] * taps[2];
+# sum3 += input[1] * taps[3];
+#
+# input += 2;
+# taps += 4;
+#
+# } while (--n_2_complex_blocks != 0);
+#
+#
+# result[0] = sum0 + sum2;
+# result[1] = sum1 + sum3;
+# }
+#
+
+# TODO: prefetch and better scheduling
+
+#include "assembly.h"
+
+
+ .file "complex_dotprod_sse64.S"
+ .version "01.01"
+.text
+ .p2align 4
+.globl GLOB_SYMB(complex_dotprod_sse)
+ DEF_FUNC_HEAD(complex_dotprod_sse)
+GLOB_SYMB(complex_dotprod_sse):
+
+ # intput: rdi, taps: rsi, n_2_ccomplex_blocks: rdx, result: rcx
+
+ mov %rdx, %rax
+
+
+ # xmm0 xmm1 xmm2 xmm3 are used to hold taps and the result of mults
+ # xmm4 xmm5 xmm6 xmm7 are used to hold the accumulated results
+
+ xorps %xmm4, %xmm4 # zero two accumulators
+ xorps %xmm5, %xmm5 # xmm5 holds zero for use below
+
+ # first handle any non-zero remainder of (n_2_complex_blocks % 4)
+
+ and $0x3, %rax
+ jmp .L1_test
+
+ .p2align 4
+.loop1:
+
+ pxor %mm0, %mm0
+ punpcklwd 0(%rdi), %mm0
+ psrad $16, %mm0
+ cvtpi2ps %mm0, %xmm0
+ shufps $0x50, %xmm0, %xmm0
+
+ mulps (%rsi), %xmm0
+ add $0x10, %rsi
+ add $4, %rdi
+ addps %xmm0, %xmm4
+.L1_test:
+ dec %rax
+ jge .loop1
+
+
+ # set up for primary loop which is unrolled 4 times
+
+ movaps %xmm5, %xmm6 # zero remaining accumulators
+ shr $2, %rdx # n_2_complex_blocks / 4
+ movaps %xmm5, %xmm7
+
+ je .cleanup # if zero, take short path
+
+ # finish setup and loop priming
+
+ pxor %mm0, %mm0
+ punpcklwd 0(%rdi), %mm0
+ psrad $16, %mm0
+ cvtpi2ps %mm0, %xmm0
+ shufps $0x50, %xmm0, %xmm0
+
+ movaps %xmm5, %xmm2
+
+ pxor %mm1, %mm1
+ punpcklwd 4(%rdi), %mm1
+ psrad $16, %mm1
+ cvtpi2ps %mm1, %xmm1
+ shufps $0x50, %xmm1, %xmm1
+
+ movaps %xmm5, %xmm3
+
+ # we know rax is not zero, we checked above,
+ # hence enter loop at top
+
+ .p2align 4
+.loop2:
+ mulps (%rsi), %xmm0
+ addps %xmm2, %xmm6
+
+ pxor %mm2, %mm2
+ punpcklwd 8(%rdi), %mm2
+ psrad $16, %mm2
+ cvtpi2ps %mm2, %xmm2
+ shufps $0x50, %xmm2, %xmm2
+
+ mulps 0x10(%rsi), %xmm1
+ addps %xmm3, %xmm7
+
+ pxor %mm3, %mm3
+ punpcklwd 12(%rdi), %mm3
+ psrad $16, %mm3
+ cvtpi2ps %mm3, %xmm3
+ shufps $0x50, %xmm3, %xmm3
+
+ mulps 0x20(%rsi), %xmm2
+ addps %xmm0, %xmm4
+
+ pxor %mm0, %mm0
+ punpcklwd 16(%rdi), %mm0
+ psrad $16, %mm0
+ cvtpi2ps %mm0, %xmm0
+ shufps $0x50, %xmm0, %xmm0
+
+ mulps 0x30(%rsi), %xmm3
+ addps %xmm1, %xmm5
+
+ pxor %mm1, %mm1
+ punpcklwd 20(%rdi), %mm1
+ psrad $16, %mm1
+ cvtpi2ps %mm1, %xmm1
+ shufps $0x50, %xmm1, %xmm1
+
+ add $0x40, %rsi
+ add $0x10, %rdi
+ dec %rdx
+ jne .loop2
+
+ # OK, now we've done with all the multiplies, but
+ # we still need to handle the unaccumulated
+ # products in xmm2 and xmm3
+
+ addps %xmm2, %xmm6
+ addps %xmm3, %xmm7
+
+ # now we want to add all accumulators into xmm4
+
+ addps %xmm5, %xmm4
+ addps %xmm6, %xmm7
+ addps %xmm7, %xmm4
+
+
+ # At this point, xmm4 contains 2x2 partial sums. We need
+ # to compute a "horizontal complex add" across xmm4.
+
+.cleanup: # xmm4 = r1 i2 r3 i4
+ movhlps %xmm4, %xmm0 # xmm0 = ?? ?? r1 r2
+ addps %xmm4, %xmm0 # xmm0 = ?? ?? r1+r3 i2+i4
+ movlps %xmm0, (%rcx) # store low 2x32 bits (complex) to memory
+
+ emms
+ retq
+
+FUNC_TAIL(complex_dotprod_sse)
+ .ident "Hand coded x86_64 SSE assembly"
diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_x86.h b/gnuradio-core/src/lib/filter/complex_dotprod_x86.h
new file mode 100644
index 0000000000..86ac0e7819
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _COMPLEX_DOTPROD_X86_H_
+#define _COMPLEX_DOTPROD_X86_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void
+complex_dotprod_3dnow (const short *input,
+ const float *taps, unsigned n_2_complex_blocks, float *result);
+
+void
+complex_dotprod_3dnowext (const short *input,
+ const float *taps, unsigned n_2_complex_blocks, float *result);
+
+void
+complex_dotprod_sse (const short *input,
+ const float *taps, unsigned n_2_complex_blocks, float *result);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _COMPLEX_DOTPROD_X86_H_ */
diff --git a/gnuradio-core/src/lib/filter/cpuid_x86.S b/gnuradio-core/src/lib/filter/cpuid_x86.S
new file mode 100644
index 0000000000..3152b91d75
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/cpuid_x86.S
@@ -0,0 +1,56 @@
+#
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+#
+# execute CPUID instruction, return EAX, EBX, ECX and EDX values in result
+#
+# void cpuid_x86 (unsigned int op, unsigned int result[4]);
+#
+
+#include "assembly.h"
+
+.file "cpuid_x86.S"
+ .version "01.01"
+.text
+.globl GLOB_SYMB(cpuid_x86)
+ DEF_FUNC_HEAD(cpuid_x86)
+GLOB_SYMB(cpuid_x86):
+ pushl %ebp
+ movl %esp, %ebp
+ pushl %ebx # must save in PIC mode, holds GOT pointer
+ pushl %esi
+
+ movl 8(%ebp), %eax # op
+ movl 12(%ebp), %esi # result
+ cpuid
+ movl %eax, 0(%esi)
+ movl %ebx, 4(%esi)
+ movl %ecx, 8(%esi)
+ movl %edx, 12(%esi)
+
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+
+FUNC_TAIL(cpuid_x86)
+ .ident "Hand coded cpuid assembly"
+
diff --git a/gnuradio-core/src/lib/filter/cpuid_x86_64.S b/gnuradio-core/src/lib/filter/cpuid_x86_64.S
new file mode 100644
index 0000000000..98137db183
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/cpuid_x86_64.S
@@ -0,0 +1,50 @@
+#
+# Copyright 2003,2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+#
+# execute CPUID instruction, return EAX, EBX, ECX and EDX values in result
+#
+# void cpuid_x86 (unsigned int op, unsigned int result[4]);
+#
+
+#include "assembly.h"
+
+.file "cpuid_x86_64.S"
+ .version "01.01"
+.text
+.globl GLOB_SYMB(cpuid_x86)
+ DEF_FUNC_HEAD(cpuid_x86)
+GLOB_SYMB(cpuid_x86):
+ mov %rbx, %r11 # must save in PIC mode, holds GOT pointer
+
+ mov %rdi, %rax # op
+ cpuid
+ movl %eax, 0(%rsi) # result
+ movl %ebx, 4(%rsi)
+ movl %ecx, 8(%rsi)
+ movl %edx, 12(%rsi)
+
+ mov %r11, %rbx
+ retq
+
+FUNC_TAIL(cpuid_x86)
+ .ident "Hand coded cpuid64 assembly"
+
diff --git a/gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow.S b/gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow.S
new file mode 100644
index 0000000000..20dc5b2d56
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow.S
@@ -0,0 +1,172 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_complex_blocks is != 0
+#
+#
+# fcomplex_dotprod_generic (const float *input,
+# const float *taps, unsigned n_2_complex_blocks, float *result)
+# {
+# float sum0 = 0;
+# float sum1 = 0;
+# float sum2 = 0;
+# float sum3 = 0;
+#
+# do {
+#
+# sum0 += input[0] * taps[0];
+# sum1 += input[0] * taps[1];
+# sum2 += input[1] * taps[2];
+# sum3 += input[1] * taps[3];
+#
+# input += 2;
+# taps += 4;
+#
+# } while (--n_2_complex_blocks != 0);
+#
+#
+# result[0] = sum0 + sum2;
+# result[1] = sum1 + sum3;
+# }
+#
+
+#include "assembly.h"
+
+
+ .file "fcomplex_dotprod_3dnow.S"
+ .version "01.01"
+.text
+ .p2align 4
+.globl GLOB_SYMB(fcomplex_dotprod_3dnow)
+ DEF_FUNC_HEAD(fcomplex_dotprod_3dnow)
+GLOB_SYMB(fcomplex_dotprod_3dnow):
+ pushl %ebp
+ movl %esp, %ebp
+ movl 8(%ebp), %eax # input
+ movl 12(%ebp), %edx # taps
+ movl 16(%ebp), %ecx
+
+ # zero accumulators
+
+ pxor %mm4, %mm4 # mm4 = 0 0
+ pxor %mm5, %mm5 # mm5 = 0 0
+ pxor %mm6, %mm6 # mm6 = 0 0
+ pxor %mm7, %mm7 # mm7 = 0 0
+
+ shrl $1, %ecx # ecx = n_2_complex_blocks / 2
+
+ movq 0(%eax), %mm0
+
+ pxor %mm2, %mm2
+ pxor %mm3, %mm3
+
+ movq %mm0, %mm1
+ punpckldq %mm0, %mm0
+ punpckhdq %mm1, %mm1
+
+
+ jmp .L1_test
+
+ #
+ # 4 taps / loop
+ # something like ?? cycles / loop
+ #
+
+ .p2align 4
+.loop1:
+ pfmul 0(%edx), %mm0
+ pfadd %mm2, %mm6
+
+ movq 8(%eax), %mm2
+
+ pfadd %mm3, %mm7
+
+ pfmul 8(%edx), %mm1
+
+ movq %mm2, %mm3
+ punpckldq %mm2, %mm2
+ punpckhdq %mm3, %mm3
+
+
+ pfmul 16(%edx), %mm2
+ pfadd %mm0, %mm4
+
+ movq 16(%eax), %mm0
+
+ pfadd %mm1, %mm5
+
+ movq %mm0, %mm1
+ punpckldq %mm0, %mm0
+
+ pfmul 24(%edx), %mm3
+
+ punpckhdq %mm1, %mm1
+
+
+#TODO: add prefetch?
+
+ addl $32, %edx
+ addl $16, %eax
+
+.L1_test:
+ decl %ecx
+ jge .loop1
+
+ # We've handled the bulk of multiplies up to here.
+ # Now accumulate the final two additions and see if original
+ # n_2_complex_blocks was odd. If so, we've got 2 more
+ # taps to do.
+
+ movl 16(%ebp), %ecx
+ pfadd %mm2, %mm6
+ andl $1, %ecx
+ pfadd %mm3, %mm7
+ je .Leven
+
+ # The count was odd, do 2 more taps.
+ # Note that we've already got mm0 and mm1 preloaded
+ # from the main loop.
+
+ pfmul 0(%edx), %mm0
+ pfadd %mm0, %mm4
+ pfmul 8(%edx), %mm1
+ pfadd %mm1, %mm5
+
+
+.Leven:
+ # at this point mm4, mm5, mm6 and mm7 contain partial sums
+
+ pfadd %mm7, %mm6
+ pfadd %mm5, %mm4
+
+ movl 20(%ebp), %eax # result
+
+ pfadd %mm6, %mm4
+
+ movq %mm4, (%eax)
+ femms
+
+ popl %ebp
+ ret
+
+FUNC_TAIL(fcomplex_dotprod_3dnow)
+ .ident "Hand coded x86 3DNow! assembly"
diff --git a/gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow64.S b/gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow64.S
new file mode 100644
index 0000000000..32772bf433
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow64.S
@@ -0,0 +1,166 @@
+#
+# Copyright 2002,2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_complex_blocks is != 0
+#
+#
+# fcomplex_dotprod_generic (const float *input,
+# const float *taps, unsigned n_2_complex_blocks, float *result)
+# {
+# float sum0 = 0;
+# float sum1 = 0;
+# float sum2 = 0;
+# float sum3 = 0;
+#
+# do {
+#
+# sum0 += input[0] * taps[0];
+# sum1 += input[0] * taps[1];
+# sum2 += input[1] * taps[2];
+# sum3 += input[1] * taps[3];
+#
+# input += 2;
+# taps += 4;
+#
+# } while (--n_2_complex_blocks != 0);
+#
+#
+# result[0] = sum0 + sum2;
+# result[1] = sum1 + sum3;
+# }
+#
+
+#include "assembly.h"
+
+
+ .file "fcomplex_dotprod_3dnow64.S"
+ .version "01.01"
+.text
+ .p2align 4
+.globl GLOB_SYMB(fcomplex_dotprod_3dnow)
+ DEF_FUNC_HEAD(fcomplex_dotprod_3dnow)
+GLOB_SYMB(fcomplex_dotprod_3dnow):
+
+ # intput: rdi, taps: rsi, n_2_ccomplex_blocks: rdx, result: rcx
+
+ mov %rdx, %rax
+
+ # zero accumulators
+
+ pxor %mm4, %mm4 # mm4 = 0 0
+ pxor %mm5, %mm5 # mm5 = 0 0
+ pxor %mm6, %mm6 # mm6 = 0 0
+ pxor %mm7, %mm7 # mm7 = 0 0
+
+ shr $1, %rax # rax = n_2_complex_blocks / 2
+
+ movq 0(%rdi), %mm0
+
+ pxor %mm2, %mm2
+ pxor %mm3, %mm3
+
+ movq %mm0, %mm1
+ punpckldq %mm0, %mm0
+ punpckhdq %mm1, %mm1
+
+
+ jmp .L1_test
+
+ #
+ # 4 taps / loop
+ # something like ?? cycles / loop
+ #
+
+ .p2align 4
+.loop1:
+ pfmul 0(%rsi), %mm0
+ pfadd %mm2, %mm6
+
+ movq 8(%rdi), %mm2
+
+ pfadd %mm3, %mm7
+
+ pfmul 8(%rsi), %mm1
+
+ movq %mm2, %mm3
+ punpckldq %mm2, %mm2
+ punpckhdq %mm3, %mm3
+
+
+ pfmul 16(%rsi), %mm2
+ pfadd %mm0, %mm4
+
+ movq 16(%rdi), %mm0
+
+ pfadd %mm1, %mm5
+
+ movq %mm0, %mm1
+ punpckldq %mm0, %mm0
+
+ pfmul 24(%rsi), %mm3
+
+ punpckhdq %mm1, %mm1
+
+
+#TODO: add prefetch?
+
+ add $32, %rsi
+ add $16, %rdi
+
+.L1_test:
+ dec %rax
+ jge .loop1
+
+ # We've handled the bulk of multiplies up to here.
+ # Now accumulate the final two additions and see if original
+ # n_2_complex_blocks was odd. If so, we've got 2 more
+ # taps to do.
+
+ pfadd %mm2, %mm6
+ and $1, %rdx
+ pfadd %mm3, %mm7
+ je .Leven
+
+ # The count was odd, do 2 more taps.
+ # Note that we've already got mm0 and mm1 preloaded
+ # from the main loop.
+
+ pfmul 0(%rsi), %mm0
+ pfadd %mm0, %mm4
+ pfmul 8(%rsi), %mm1
+ pfadd %mm1, %mm5
+
+
+.Leven:
+ # at this point mm4, mm5, mm6 and mm7 contain partial sums
+
+ pfadd %mm7, %mm6
+ pfadd %mm5, %mm4
+ pfadd %mm6, %mm4
+
+ movq %mm4, (%rcx) # result
+ femms
+
+ retq
+
+FUNC_TAIL(fcomplex_dotprod_3dnow)
+ .ident "Hand coded x86_64 3DNow! assembly"
diff --git a/gnuradio-core/src/lib/filter/fcomplex_dotprod_sse.S b/gnuradio-core/src/lib/filter/fcomplex_dotprod_sse.S
new file mode 100644
index 0000000000..2d8b4ccb30
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/fcomplex_dotprod_sse.S
@@ -0,0 +1,184 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_complex_blocks is != 0
+#
+#
+# fcomplex_dotprod_generic (const float *input,
+# const float *taps, unsigned n_2_complex_blocks, float *result)
+# {
+# float sum0 = 0;
+# float sum1 = 0;
+# float sum2 = 0;
+# float sum3 = 0;
+#
+# do {
+#
+# sum0 += input[0] * taps[0];
+# sum1 += input[0] * taps[1];
+# sum2 += input[1] * taps[2];
+# sum3 += input[1] * taps[3];
+#
+# input += 2;
+# taps += 4;
+#
+# } while (--n_2_complex_blocks != 0);
+#
+#
+# result[0] = sum0 + sum2;
+# result[1] = sum1 + sum3;
+# }
+#
+
+# TODO: prefetch and better scheduling
+
+#include "assembly.h"
+
+
+ .file "fcomplex_dotprod_sse.S"
+ .version "01.01"
+.text
+ .p2align 4
+.globl GLOB_SYMB(fcomplex_dotprod_sse)
+ DEF_FUNC_HEAD(fcomplex_dotprod_sse)
+GLOB_SYMB(fcomplex_dotprod_sse):
+ pushl %ebp
+ movl %esp, %ebp
+ movl 8(%ebp), %eax # input
+ movl 12(%ebp), %edx # taps
+ movl 16(%ebp), %ecx
+
+
+ # xmm0 xmm1 xmm2 xmm3 are used to hold taps and the result of mults
+ # xmm4 xmm5 xmm6 xmm7 are used to hold the accumulated results
+
+ xorps %xmm4, %xmm4 # zero two accumulators
+ xorps %xmm5, %xmm5 # xmm5 holds zero for use below
+
+ # first handle any non-zero remainder of (n_2_complex_blocks % 4)
+
+ andl $0x3, %ecx
+ jmp .L1_test
+
+ .p2align 4
+.loop1:
+
+ movlps 0(%eax), %xmm0
+ shufps $0x50, %xmm0, %xmm0 # b01010000
+
+ mulps (%edx), %xmm0
+ addl $0x10, %edx
+ addl $8, %eax
+ addps %xmm0, %xmm4
+.L1_test:
+ decl %ecx
+ jge .loop1
+
+
+ # set up for primary loop which is unrolled 4 times
+
+ movl 16(%ebp), %ecx
+ movaps %xmm5, %xmm6 # zero remaining accumulators
+ movaps %xmm5, %xmm7
+
+ shrl $2, %ecx # n_2_complex_blocks / 4
+ je .cleanup # if zero, take short path
+
+ # finish setup and loop priming
+
+ movlps 0(%eax), %xmm0
+
+ movaps %xmm5, %xmm2
+ movaps %xmm5, %xmm3
+
+ movlps 8(%eax), %xmm1
+ shufps $0x50, %xmm0, %xmm0
+
+ shufps $0x50, %xmm1, %xmm1
+
+ # we know ecx is not zero, we checked above,
+ # hence enter loop at top
+
+ .p2align 4
+.loop2:
+ addps %xmm2, %xmm6
+ movlps 0x10(%eax), %xmm2
+
+ addps %xmm3, %xmm7
+
+ mulps (%edx), %xmm0
+
+ movlps 0x18(%eax), %xmm3
+ shufps $0x50, %xmm2, %xmm2
+
+ mulps 0x10(%edx), %xmm1
+
+ shufps $0x50, %xmm3, %xmm3
+
+ addps %xmm0, %xmm4
+ movlps 0x20(%eax), %xmm0
+
+ addps %xmm1, %xmm5
+
+ mulps 0x20(%edx), %xmm2
+
+ movlps 0x28(%eax), %xmm1
+ shufps $0x50, %xmm0, %xmm0
+
+ mulps 0x30(%edx), %xmm3
+
+ shufps $0x50, %xmm1, %xmm1
+
+ addl $0x40, %edx
+ addl $0x20, %eax
+ decl %ecx
+ jne .loop2
+
+ # OK, now we've done with all the multiplies, but
+ # we still need to handle the unaccumulated
+ # products in xmm2 and xmm3
+
+ addps %xmm2, %xmm6
+ addps %xmm3, %xmm7
+
+ # now we want to add all accumulators into xmm4
+
+ addps %xmm5, %xmm4
+ addps %xmm6, %xmm7
+ addps %xmm7, %xmm4
+
+
+ # At this point, xmm4 contains 2x2 partial sums. We need
+ # to compute a "horizontal complex add" across xmm4.
+
+.cleanup: # xmm4 = r1 i2 r3 i4
+ movl 20(%ebp), %eax # @result
+ movhlps %xmm4, %xmm0 # xmm0 = ?? ?? r1 r2
+ addps %xmm4, %xmm0 # xmm0 = ?? ?? r1+r3 i2+i4
+ movlps %xmm0, (%eax) # store low 2x32 bits (complex) to memory
+
+ popl %ebp
+ ret
+
+FUNC_TAIL(fcomplex_dotprod_sse)
+ .ident "Hand coded x86 SSE assembly"
diff --git a/gnuradio-core/src/lib/filter/fcomplex_dotprod_sse64.S b/gnuradio-core/src/lib/filter/fcomplex_dotprod_sse64.S
new file mode 100644
index 0000000000..cba035795d
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/fcomplex_dotprod_sse64.S
@@ -0,0 +1,179 @@
+#
+# Copyright 2002,2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_complex_blocks is != 0
+#
+#
+# fcomplex_dotprod_generic (const float *input,
+# const float *taps, unsigned n_2_complex_blocks, float *result)
+# {
+# float sum0 = 0;
+# float sum1 = 0;
+# float sum2 = 0;
+# float sum3 = 0;
+#
+# do {
+#
+# sum0 += input[0] * taps[0];
+# sum1 += input[0] * taps[1];
+# sum2 += input[1] * taps[2];
+# sum3 += input[1] * taps[3];
+#
+# input += 2;
+# taps += 4;
+#
+# } while (--n_2_complex_blocks != 0);
+#
+#
+# result[0] = sum0 + sum2;
+# result[1] = sum1 + sum3;
+# }
+#
+
+# TODO: prefetch and better scheduling
+
+#include "assembly.h"
+
+
+ .file "fcomplex_dotprod_sse64.S"
+ .version "01.01"
+.text
+ .p2align 4
+.globl GLOB_SYMB(fcomplex_dotprod_sse)
+ DEF_FUNC_HEAD(fcomplex_dotprod_sse)
+GLOB_SYMB(fcomplex_dotprod_sse):
+
+ # intput: rdi, taps: rsi, n_2_ccomplex_blocks: rdx, result: rcx
+
+ mov %rdx, %rax
+
+ # xmm0 xmm1 xmm2 xmm3 are used to hold taps and the result of mults
+ # xmm4 xmm5 xmm6 xmm7 are used to hold the accumulated results
+
+ xorps %xmm4, %xmm4 # zero two accumulators
+ xorps %xmm5, %xmm5 # xmm5 holds zero for use below
+
+ # first handle any non-zero remainder of (n_2_complex_blocks % 4)
+
+ and $0x3, %rax
+ jmp .L1_test
+
+ .p2align 4
+.loop1:
+
+ movlps 0(%rdi), %xmm0
+ shufps $0x50, %xmm0, %xmm0 # b01010000
+
+ mulps (%rsi), %xmm0
+ add $0x10, %rsi
+ add $8, %rdi
+ addps %xmm0, %xmm4
+.L1_test:
+ dec %rax
+ jge .loop1
+
+
+ # set up for primary loop which is unrolled 4 times
+
+ movaps %xmm5, %xmm6 # zero remaining accumulators
+ movaps %xmm5, %xmm7
+
+ shr $2, %rdx # n_2_complex_blocks / 4
+ je .cleanup # if zero, take short path
+
+ # finish setup and loop priming
+
+ movlps 0(%rdi), %xmm0
+
+ movaps %xmm5, %xmm2
+ movaps %xmm5, %xmm3
+
+ movlps 8(%rdi), %xmm1
+ shufps $0x50, %xmm0, %xmm0
+
+ shufps $0x50, %xmm1, %xmm1
+
+ # we know rdx is not zero, we checked above,
+ # hence enter loop at top
+
+ .p2align 4
+.loop2:
+ addps %xmm2, %xmm6
+ movlps 0x10(%rdi), %xmm2
+
+ addps %xmm3, %xmm7
+
+ mulps (%rsi), %xmm0
+
+ movlps 0x18(%rdi), %xmm3
+ shufps $0x50, %xmm2, %xmm2
+
+ mulps 0x10(%rsi), %xmm1
+
+ shufps $0x50, %xmm3, %xmm3
+
+ addps %xmm0, %xmm4
+ movlps 0x20(%rdi), %xmm0
+
+ addps %xmm1, %xmm5
+
+ mulps 0x20(%rsi), %xmm2
+
+ movlps 0x28(%rdi), %xmm1
+ shufps $0x50, %xmm0, %xmm0
+
+ mulps 0x30(%rsi), %xmm3
+
+ shufps $0x50, %xmm1, %xmm1
+
+ add $0x40, %rsi
+ add $0x20, %rdi
+ dec %rdx
+ jne .loop2
+
+ # OK, now we've done with all the multiplies, but
+ # we still need to handle the unaccumulated
+ # products in xmm2 and xmm3
+
+ addps %xmm2, %xmm6
+ addps %xmm3, %xmm7
+
+ # now we want to add all accumulators into xmm4
+
+ addps %xmm5, %xmm4
+ addps %xmm6, %xmm7
+ addps %xmm7, %xmm4
+
+
+ # At this point, xmm4 contains 2x2 partial sums. We need
+ # to compute a "horizontal complex add" across xmm4.
+
+.cleanup: # xmm4 = r1 i2 r3 i4
+ movhlps %xmm4, %xmm0 # xmm0 = ?? ?? r1 r2
+ addps %xmm4, %xmm0 # xmm0 = ?? ?? r1+r3 i2+i4
+ movlps %xmm0, (%rcx) # store low 2x32 bits (complex) to memory
+
+ retq
+
+FUNC_TAIL(fcomplex_dotprod_sse)
+ .ident "Hand coded x86_64 SSE assembly"
diff --git a/gnuradio-core/src/lib/filter/fcomplex_dotprod_x86.h b/gnuradio-core/src/lib/filter/fcomplex_dotprod_x86.h
new file mode 100644
index 0000000000..d9f7eaca22
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _FCOMPLEX_DOTPROD_X86_H_
+#define _FCOMPLEX_DOTPROD_X86_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void
+fcomplex_dotprod_3dnow (const float *input,
+ const float *taps, unsigned n_2_complex_blocks, float *result);
+
+void
+fcomplex_dotprod_sse (const float *input,
+ const float *taps, unsigned n_2_complex_blocks, float *result);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FCOMPLEX_DOTPROD_X86_H_ */
diff --git a/gnuradio-core/src/lib/filter/filter.i b/gnuradio-core/src/lib/filter/filter.i
new file mode 100644
index 0000000000..2d434699e3
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/filter.i
@@ -0,0 +1,45 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+%{
+#include <gr_iir_filter_ffd.h>
+#include <gr_single_pole_iir_filter_ff.h>
+#include <gr_single_pole_iir_filter_cc.h>
+#include <gr_hilbert_fc.h>
+#include <gr_filter_delay_fc.h>
+#include <gr_fft_filter_ccc.h>
+#include <gr_fft_filter_fff.h>
+#include <gr_goertzel_fc.h>
+#include <gr_cma_equalizer_cc.h>
+%}
+
+%include "gr_iir_filter_ffd.i"
+%include "gr_single_pole_iir_filter_ff.i"
+%include "gr_single_pole_iir_filter_cc.i"
+%include "gr_hilbert_fc.i"
+%include "gr_filter_delay_fc.i"
+%include "gr_fft_filter_ccc.i"
+%include "gr_fft_filter_fff.i"
+%include "gr_goertzel_fc.i"
+%include "gr_cma_equalizer_cc.i"
+
+%include "filter_generated.i"
diff --git a/gnuradio-core/src/lib/filter/float_dotprod_3dnow.S b/gnuradio-core/src/lib/filter/float_dotprod_3dnow.S
new file mode 100644
index 0000000000..784fa0b55c
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/float_dotprod_3dnow.S
@@ -0,0 +1,148 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_4_float_blocks is != 0
+#
+#
+# float
+# float_dotprod_generic (const float *input,
+# const float *taps, unsigned n_4_float_blocks)
+# {
+# float sum0 = 0;
+# float sum1 = 0;
+# float sum2 = 0;
+# float sum3 = 0;
+#
+# do {
+#
+# sum0 += input[0] * taps[0];
+# sum1 += input[1] * taps[1];
+# sum2 += input[2] * taps[2];
+# sum3 += input[3] * taps[3];
+#
+# input += 4;
+# taps += 4;
+#
+# } while (--n_4_float_blocks != 0);
+#
+#
+# return sum0 + sum1 + sum2 + sum3;
+# }
+#
+
+#include "assembly.h"
+
+
+ .file "float_dotprod_3dnow.S"
+ .version "01.01"
+.text
+ .p2align 4
+.globl GLOB_SYMB(float_dotprod_3dnow)
+ DEF_FUNC_HEAD(float_dotprod_3dnow)
+GLOB_SYMB(float_dotprod_3dnow):
+ pushl %ebp
+ movl %esp, %ebp
+ movl 8(%ebp), %edx
+ movl 12(%ebp), %eax
+ movl 16(%ebp), %ecx
+
+ # zero accumulators
+
+ pxor %mm4, %mm4 # mm4 = 0 0
+ pxor %mm5, %mm5 # mm5 = 0 0
+ pxor %mm6, %mm6 # mm6 = 0 0
+ pxor %mm7, %mm7 # mm7 = 0 0
+
+ shrl $1, %ecx # ecx = n_4_float_blocks / 2
+ movq 0(%eax), %mm0
+ movq 8(%eax), %mm1
+ pxor %mm2, %mm2
+ pxor %mm3, %mm3
+ jmp .L1_test
+
+ #
+ # 8 taps / loop
+ # something like 6 cycles / loop
+ #
+
+ .p2align 4
+.loop1:
+ pfmul 0(%edx), %mm0
+ pfadd %mm2, %mm6
+ movq 16(%eax), %mm2
+
+ pfmul 8(%edx), %mm1
+ pfadd %mm3, %mm7
+ movq 24(%eax), %mm3
+
+ pfmul 16(%edx), %mm2
+ pfadd %mm0, %mm4
+ movq 32(%eax), %mm0
+
+ pfmul 24(%edx), %mm3
+ pfadd %mm1, %mm5
+ movq 40(%eax), %mm1
+
+ addl $32, %edx
+ addl $32, %eax
+.L1_test:
+ decl %ecx
+ jge .loop1
+
+ # We've handled the bulk of multiplies up to here.
+ # Now accumulate the final two additions and see if original
+ # n_4_float_blocks was odd. If so, we've got 4 more
+ # taps to do.
+
+ movl 16(%ebp), %ecx
+ pfadd %mm2, %mm6
+ andl $1, %ecx
+ pfadd %mm3, %mm7
+ je .Leven
+
+ # The count was odd, do 4 more taps.
+ # Note that we've already got mm0 and mm1 preloaded
+ # from the main loop.
+
+ pfmul 0(%edx), %mm0
+ pfadd %mm0, %mm4
+ pfmul 8(%edx), %mm1
+ pfadd %mm1, %mm5
+
+.Leven:
+ # at this point mm4, mm5, mm6 and mm7 contain partial sums
+
+ pfadd %mm7, %mm6
+ pfadd %mm5, %mm4
+ pfadd %mm6, %mm4
+ pfacc %mm4, %mm4
+
+ movd %mm4, 16(%ebp)
+ femms
+ flds 16(%ebp)
+
+ popl %ebp
+ ret
+
+FUNC_TAIL(float_dotprod_3dnow)
+ .ident "Hand coded x86 3DNow! assembly"
diff --git a/gnuradio-core/src/lib/filter/float_dotprod_3dnow64.S b/gnuradio-core/src/lib/filter/float_dotprod_3dnow64.S
new file mode 100644
index 0000000000..0f6a948067
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/float_dotprod_3dnow64.S
@@ -0,0 +1,145 @@
+#
+# Copyright 2002,2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_4_float_blocks is != 0
+#
+#
+# float
+# float_dotprod_generic (const float *input,
+# const float *taps, unsigned n_4_float_blocks)
+# {
+# float sum0 = 0;
+# float sum1 = 0;
+# float sum2 = 0;
+# float sum3 = 0;
+#
+# do {
+#
+# sum0 += input[0] * taps[0];
+# sum1 += input[1] * taps[1];
+# sum2 += input[2] * taps[2];
+# sum3 += input[3] * taps[3];
+#
+# input += 4;
+# taps += 4;
+#
+# } while (--n_4_float_blocks != 0);
+#
+#
+# return sum0 + sum1 + sum2 + sum3;
+# }
+#
+
+#include "assembly.h"
+
+
+ .file "float_dotprod_3dnow64.S"
+ .version "01.01"
+.text
+ .p2align 4
+.globl GLOB_SYMB(float_dotprod_3dnow)
+ DEF_FUNC_HEAD(float_dotprod_3dnow)
+GLOB_SYMB(float_dotprod_3dnow):
+
+ # intput: rdi, taps: rsi, n_2_ccomplex_blocks: rdx
+
+ mov %rdx, %rax
+
+ # zero accumulators
+
+ pxor %mm4, %mm4 # mm4 = 0 0
+ pxor %mm5, %mm5 # mm5 = 0 0
+ pxor %mm6, %mm6 # mm6 = 0 0
+ pxor %mm7, %mm7 # mm7 = 0 0
+
+ shr $1, %rax # rax = n_4_float_blocks / 2
+ movq 0(%rsi), %mm0
+ movq 8(%rsi), %mm1
+ pxor %mm2, %mm2
+ pxor %mm3, %mm3
+ jmp .L1_test
+
+ #
+ # 8 taps / loop
+ # something like 6 cycles / loop
+ #
+
+ .p2align 4
+.loop1:
+ pfmul 0(%rdi), %mm0
+ pfadd %mm2, %mm6
+ movq 16(%rsi), %mm2
+
+ pfmul 8(%rdi), %mm1
+ pfadd %mm3, %mm7
+ movq 24(%rsi), %mm3
+
+ pfmul 16(%rdi), %mm2
+ pfadd %mm0, %mm4
+ movq 32(%rsi), %mm0
+
+ pfmul 24(%rdi), %mm3
+ pfadd %mm1, %mm5
+ movq 40(%rsi), %mm1
+
+ add $32, %rdi
+ add $32, %rsi
+.L1_test:
+ dec %rax
+ jge .loop1
+
+ # We've handled the bulk of multiplies up to here.
+ # Now accumulate the final two additions and see if original
+ # n_4_float_blocks was odd. If so, we've got 4 more
+ # taps to do.
+
+ pfadd %mm2, %mm6
+ and $1, %rdx
+ pfadd %mm3, %mm7
+ je .Leven
+
+ # The count was odd, do 4 more taps.
+ # Note that we've already got mm0 and mm1 preloaded
+ # from the main loop.
+
+ pfmul 0(%rdi), %mm0
+ pfadd %mm0, %mm4
+ pfmul 8(%rdi), %mm1
+ pfadd %mm1, %mm5
+
+.Leven:
+ # at this point mm4, mm5, mm6 and mm7 contain partial sums
+
+ pfadd %mm7, %mm6
+ pfadd %mm5, %mm4
+ pfadd %mm6, %mm4
+ pfacc %mm4, %mm4
+
+ movd %mm4, -8(%rsp)
+ movss -8(%rsp), %xmm0
+ femms
+
+ retq
+
+FUNC_TAIL(float_dotprod_3dnow)
+ .ident "Hand coded x86_64 3DNow! assembly"
diff --git a/gnuradio-core/src/lib/filter/float_dotprod_generic.c b/gnuradio-core/src/lib/filter/float_dotprod_generic.c
new file mode 100644
index 0000000000..21912afd2d
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "float_dotprod_generic.h"
+
+
+float
+float_dotprod_generic (const float *input,
+ const float *taps, unsigned n_4_float_blocks)
+{
+ float sum0 = 0;
+ float sum1 = 0;
+ float sum2 = 0;
+ float sum3 = 0;
+
+ do {
+
+ sum0 += input[0] * taps[0];
+ sum1 += input[1] * taps[1];
+ sum2 += input[2] * taps[2];
+ sum3 += input[3] * taps[3];
+
+ input += 4;
+ taps += 4;
+
+ } while (--n_4_float_blocks != 0);
+
+
+ return sum0 + sum1 + sum2 + sum3;
+}
diff --git a/gnuradio-core/src/lib/filter/float_dotprod_generic.h b/gnuradio-core/src/lib/filter/float_dotprod_generic.h
new file mode 100644
index 0000000000..4f4d4ebf36
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _FLOAT_DOTPROD_GENERIC_H_
+#define _FLOAT_DOTPROD_GENERIC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+float
+float_dotprod_generic (const float *input,
+ const float *taps, unsigned n_4_float_blocks);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _FLOAT_DOTPROD_GENERIC_H_ */
diff --git a/gnuradio-core/src/lib/filter/float_dotprod_sse.S b/gnuradio-core/src/lib/filter/float_dotprod_sse.S
new file mode 100644
index 0000000000..0e59f5e3bf
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/float_dotprod_sse.S
@@ -0,0 +1,167 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_4_float_blocks is != 0
+#
+#
+# float
+# float_dotprod_generic (const float *input,
+# const float *taps, unsigned n_4_float_blocks)
+# {
+# float sum0 = 0;
+# float sum1 = 0;
+# float sum2 = 0;
+# float sum3 = 0;
+#
+# do {
+#
+# sum0 += input[0] * taps[0];
+# sum1 += input[1] * taps[1];
+# sum2 += input[2] * taps[2];
+# sum3 += input[3] * taps[3];
+#
+# input += 4;
+# taps += 4;
+#
+# } while (--n_4_float_blocks != 0);
+#
+#
+# return sum0 + sum1 + sum2 + sum3;
+# }
+#
+
+#include "assembly.h"
+
+
+ .file "float_dotprod_sse.S"
+ .version "01.01"
+.text
+ .p2align 4
+.globl GLOB_SYMB(float_dotprod_sse)
+ DEF_FUNC_HEAD(float_dotprod_sse)
+GLOB_SYMB(float_dotprod_sse):
+ pushl %ebp
+ movl %esp, %ebp
+ movl 8(%ebp), %edx
+ movl 12(%ebp), %eax
+ movl 16(%ebp), %ecx
+
+
+ # xmm0 xmm1 xmm2 xmm3 are used to hold taps and the result of mults
+ # xmm4 xmm5 xmm6 xmm7 are used to hold the accumulated results
+
+ xorps %xmm4, %xmm4 # zero two accumulators
+ xorps %xmm5, %xmm5 # xmm5 holds zero for use below
+
+ # first handle any non-zero remainder of (n_4_float_blocks % 4)
+
+ andl $0x3, %ecx
+ jmp .L1_test
+
+ .p2align 4
+.loop1:
+ movaps (%eax), %xmm0
+ mulps (%edx), %xmm0
+ addl $0x10, %edx
+ addl $0x10, %eax
+ addps %xmm0, %xmm4
+.L1_test:
+ decl %ecx
+ jge .loop1
+
+
+ # set up for primary loop which is unrolled 4 times
+
+ movl 16(%ebp), %ecx
+ movaps %xmm5, %xmm6 # zero remaining accumulators
+ movaps %xmm5, %xmm7
+
+ shrl $2, %ecx # n_4_float_blocks / 4
+ je .cleanup # if zero, take short path
+
+ # finish setup and loop priming
+
+ movaps 0x00(%eax), %xmm0
+ movaps %xmm5, %xmm2
+ movaps 0x10(%eax), %xmm1
+ movaps %xmm5, %xmm3
+
+ # we know ecx is not zero, we checked above,
+ # hence enter loop at top
+
+ .p2align 4
+.loop2:
+ mulps (%edx), %xmm0
+ addps %xmm2, %xmm6
+ movaps 0x20(%eax), %xmm2
+
+ mulps 0x10(%edx), %xmm1
+ addps %xmm3, %xmm7
+ movaps 0x30(%eax), %xmm3
+
+ mulps 0x20(%edx), %xmm2
+ addps %xmm0, %xmm4
+ movaps 0x40(%eax), %xmm0
+
+ mulps 0x30(%edx), %xmm3
+ addps %xmm1, %xmm5
+ movaps 0x50(%eax), %xmm1
+
+ addl $0x40, %edx
+ addl $0x40, %eax
+ decl %ecx
+ jne .loop2
+
+ # OK, now we've done with all the multiplies, but
+ # we still need to handle the unaccumulated
+ # products in xmm2 and xmm3
+
+ addps %xmm2, %xmm6
+ addps %xmm3, %xmm7
+
+ # now we want to add all accumulators into xmm4
+
+ addps %xmm5, %xmm4
+ addps %xmm6, %xmm7
+ addps %xmm7, %xmm4
+
+
+ # At this point, xmm4 contains 4 partial sums. We need
+ # to compute a "horizontal add" across xmm4.
+ # This is a fairly nasty operation...
+
+.cleanup: # xmm4 = d1 d2 d3 d4
+ xorps %xmm0, %xmm0 # xmm0 = 0 0 0 0 (may be unnecessary)
+ movhlps %xmm4, %xmm0 # xmm0 = 0 0 d1 d2
+ addps %xmm4, %xmm0 # xmm0 = d1 d2 d1+d3 d2+d4
+ movaps %xmm0, %xmm1 # xmm1 = d1 d2 d1+d3 d2+d4
+ shufps $0xE1, %xmm4, %xmm1 # xmm1 = d1 d2 d2+d4 d1+d3
+ addss %xmm1, %xmm0 # xmm1 = d1 d2 d1+d3 d1+d2+d3+d4
+ movss %xmm0, 16(%ebp) # store low 32 bits (sum) to memory
+ flds 16(%ebp) # and load onto FPU stack for return
+
+ popl %ebp
+ ret
+
+FUNC_TAIL(float_dotprod_sse)
+ .ident "Hand coded x86 SSE assembly"
diff --git a/gnuradio-core/src/lib/filter/float_dotprod_sse64.S b/gnuradio-core/src/lib/filter/float_dotprod_sse64.S
new file mode 100644
index 0000000000..c7f821a3df
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/float_dotprod_sse64.S
@@ -0,0 +1,161 @@
+#
+# Copyright 2002,2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_4_float_blocks is != 0
+#
+#
+# float
+# float_dotprod_generic (const float *input,
+# const float *taps, unsigned n_4_float_blocks)
+# {
+# float sum0 = 0;
+# float sum1 = 0;
+# float sum2 = 0;
+# float sum3 = 0;
+#
+# do {
+#
+# sum0 += input[0] * taps[0];
+# sum1 += input[1] * taps[1];
+# sum2 += input[2] * taps[2];
+# sum3 += input[3] * taps[3];
+#
+# input += 4;
+# taps += 4;
+#
+# } while (--n_4_float_blocks != 0);
+#
+#
+# return sum0 + sum1 + sum2 + sum3;
+# }
+#
+
+#include "assembly.h"
+
+
+ .file "float_dotprod_sse64.S"
+ .version "01.01"
+.text
+ .p2align 4
+.globl GLOB_SYMB(float_dotprod_sse)
+ DEF_FUNC_HEAD(float_dotprod_sse)
+GLOB_SYMB(float_dotprod_sse):
+
+ # intput: rdi, taps: rsi, n_2_ccomplex_blocks: rdx
+
+ mov %rdx, %rax
+
+ # xmm0 xmm1 xmm2 xmm3 are used to hold taps and the result of mults
+ # xmm4 xmm5 xmm6 xmm7 are used to hold the accumulated results
+
+ xorps %xmm4, %xmm4 # zero two accumulators
+ xorps %xmm5, %xmm5 # xmm5 holds zero for use below
+
+ # first handle any non-zero remainder of (n_4_float_blocks % 4)
+
+ and $0x3, %rax
+ jmp .L1_test
+
+ .p2align 4
+.loop1:
+ movaps (%rsi), %xmm0
+ mulps (%rdi), %xmm0
+ add $0x10, %rdi
+ add $0x10, %rsi
+ addps %xmm0, %xmm4
+.L1_test:
+ dec %rax
+ jge .loop1
+
+
+ # set up for primary loop which is unrolled 4 times
+
+ movaps %xmm5, %xmm6 # zero remaining accumulators
+ movaps %xmm5, %xmm7
+
+ shr $2, %rdx # n_4_float_blocks / 4
+ je .cleanup # if zero, take short path
+
+ # finish setup and loop priming
+
+ movaps 0x00(%rsi), %xmm0
+ movaps %xmm5, %xmm2
+ movaps 0x10(%rsi), %xmm1
+ movaps %xmm5, %xmm3
+
+ # we know rdx is not zero, we checked above,
+ # hence enter loop at top
+
+ .p2align 4
+.loop2:
+ mulps (%rdi), %xmm0
+ addps %xmm2, %xmm6
+ movaps 0x20(%rsi), %xmm2
+
+ mulps 0x10(%rdi), %xmm1
+ addps %xmm3, %xmm7
+ movaps 0x30(%rsi), %xmm3
+
+ mulps 0x20(%rdi), %xmm2
+ addps %xmm0, %xmm4
+ movaps 0x40(%rsi), %xmm0
+
+ mulps 0x30(%rdi), %xmm3
+ addps %xmm1, %xmm5
+ movaps 0x50(%rsi), %xmm1
+
+ add $0x40, %rdi
+ add $0x40, %rsi
+ dec %rdx
+ jne .loop2
+
+ # OK, now we've done with all the multiplies, but
+ # we still need to handle the unaccumulated
+ # products in xmm2 and xmm3
+
+ addps %xmm2, %xmm6
+ addps %xmm3, %xmm7
+
+ # now we want to add all accumulators into xmm4
+
+ addps %xmm5, %xmm4
+ addps %xmm6, %xmm7
+ addps %xmm7, %xmm4
+
+
+ # At this point, xmm4 contains 4 partial sums. We need
+ # to compute a "horizontal add" across xmm4.
+ # This is a fairly nasty operation...
+
+.cleanup: # xmm4 = d1 d2 d3 d4
+ xorps %xmm0, %xmm0 # xmm0 = 0 0 0 0 (may be unnecessary)
+ movhlps %xmm4, %xmm0 # xmm0 = 0 0 d1 d2
+ addps %xmm4, %xmm0 # xmm0 = d1 d2 d1+d3 d2+d4
+ movaps %xmm0, %xmm1 # xmm1 = d1 d2 d1+d3 d2+d4
+ shufps $0xE1, %xmm4, %xmm1 # xmm1 = d1 d2 d2+d4 d1+d3
+ addss %xmm1, %xmm0 # xmm1 = d1 d2 d1+d3 d1+d2+d3+d4
+
+ retq
+
+FUNC_TAIL(float_dotprod_sse)
+ .ident "Hand coded x86_64 SSE assembly"
diff --git a/gnuradio-core/src/lib/filter/float_dotprod_x86.h b/gnuradio-core/src/lib/filter/float_dotprod_x86.h
new file mode 100644
index 0000000000..7a101920c8
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _FLOAT_DOTPROD_X86_H_
+#define _FLOAT_DOTPROD_X86_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+float
+float_dotprod_3dnow (const float *input,
+ const float *taps, unsigned n_4_float_blocks);
+
+float
+float_dotprod_sse (const float *input,
+ const float *taps, unsigned n_4_float_blocks);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _FLOAT_DOTPROD_X86_H_ */
diff --git a/gnuradio-core/src/lib/filter/generate_all.py b/gnuradio-core/src/lib/filter/generate_all.py
new file mode 100755
index 0000000000..dcbe75df08
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/generate_all.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+#
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+from build_utils import output_glue
+
+import generate_gr_fir_filter_XXX
+import generate_gr_interp_fir_filter_XXX
+import generate_gr_rational_resampler_base_XXX
+import generate_gr_freq_xlating_fir_filter_XXX
+import generate_gr_fir_sysconfig_generic
+import generate_gr_fir_sysconfig
+import generate_gr_fir_util
+import generate_gr_fir_XXX
+
+def generate_all():
+ generate_gr_fir_XXX.generate()
+ generate_gr_fir_filter_XXX.generate()
+ generate_gr_interp_fir_filter_XXX.generate()
+ generate_gr_rational_resampler_base_XXX.generate()
+ generate_gr_freq_xlating_fir_filter_XXX.generate()
+ generate_gr_fir_sysconfig_generic.generate()
+ generate_gr_fir_sysconfig.generate()
+ generate_gr_fir_util.generate()
+ output_glue('filter')
+
+if __name__ == '__main__':
+ generate_all()
diff --git a/gnuradio-core/src/lib/filter/generate_gr_fir_XXX.py b/gnuradio-core/src/lib/filter/generate_gr_fir_XXX.py
new file mode 100755
index 0000000000..e55ff85400
--- /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 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+import re
+from generate_utils import *
+
+roots = ['gr_fir_XXX', 'gr_fir_XXX_generic']
+
+
+# figure out accumulator type. Use biggest of input, output and tap type
+
+def code3_to_acc_code (code3):
+ if i_code (code3) == 'c' or o_code (code3) == 'c' or tap_code (code3) == 'c':
+ return 'c'
+ if i_code (code3) == 'f' or o_code (code3) == 'f' or tap_code (code3) == 'f':
+ return 'f'
+ if i_code (code3) == 'i' or o_code (code3) == 'i' or tap_code (code3) == 'i':
+ return 'i'
+ return 'i' # even short short short needs int accumulator
+
+
+def code3_to_input_cast (code3):
+ if i_code (code3) == 's' and o_code (code3) == 'c':
+ return '(float)'
+ return ''
+
+def expand_h_cc (root, code3):
+ d = init_dict (root, code3)
+ expand_template (d, root + '.h.t')
+ expand_template (d, root + '.cc.t')
+
+def init_dict (root, code3):
+ name = re.sub ('X+', code3, root)
+ d = standard_dict (name, code3)
+ d['FIR_TYPE'] = 'gr_fir_' + code3
+ d['INPUT_CAST'] = code3_to_input_cast (code3)
+ acc_code = code3_to_acc_code (code3)
+ d['ACC_TYPE'] = char_to_type[acc_code]
+ if acc_code == 'c':
+ d['N_UNROLL'] = '2'
+ d['VRCOMPLEX_INCLUDE'] = '#include <gr_types.h>'
+ else:
+ d['N_UNROLL'] = '4'
+ d['VRCOMPLEX_INCLUDE'] = ''
+ return d
+
+
+def generate ():
+ for r in roots:
+ for s in fir_signatures:
+ expand_h_cc (r, s)
+
+
+if __name__ == '__main__':
+ generate ()
diff --git a/gnuradio-core/src/lib/filter/generate_gr_fir_filter_XXX.py b/gnuradio-core/src/lib/filter/generate_gr_fir_filter_XXX.py
new file mode 100755
index 0000000000..e3c0ec7a00
--- /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 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+import re
+from generate_utils import *
+
+roots = ['gr_fir_filter_XXX']
+
+
+def expand_h_cc_i (root, code3):
+ d = init_dict (root, code3)
+ expand_template (d, root + '.h.t')
+ expand_template (d, root + '.cc.t')
+ expand_template (d, root + '.i.t')
+
+def init_dict (root, code3):
+ name = re.sub ('X+', code3, root)
+ d = standard_dict (name, code3)
+ d['FIR_TYPE'] = 'gr_fir_' + code3
+ return d
+
+def generate ():
+ for r in roots:
+ for s in fir_signatures:
+ expand_h_cc_i (r, s)
+
+if __name__ == '__main__':
+ generate ()
+
diff --git a/gnuradio-core/src/lib/filter/generate_gr_fir_sysconfig.py b/gnuradio-core/src/lib/filter/generate_gr_fir_sysconfig.py
new file mode 100755
index 0000000000..3c78daa2d4
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/generate_gr_fir_sysconfig.py
@@ -0,0 +1,127 @@
+#!/bin/env python
+# -*- python -*-
+#
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+from generate_utils import *
+
+
+# ----------------------------------------------------------------
+
+def make_gr_fir_sysconfig_h ():
+ out = open_and_log_name ('gr_fir_sysconfig.h', 'w')
+ out.write (copyright)
+
+ out.write (
+'''
+/*
+ * WARNING: This file is automatically generated by generate_gr_fir_sysconfig.py
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifndef INCLUDED_GR_FIR_SYSCONFIG_H
+#define INCLUDED_GR_FIR_SYSCONFIG_H
+
+#include <gr_types.h>
+
+''')
+
+ # for sig in fir_signatures:
+ # out.write ('class gr_fir_' + sig + ';\n')
+
+ out.write ('#include <gr_fir_util.h>\n')
+
+ out.write (
+'''
+/*!
+ * \\brief abstract base class for configuring the automatic selection of the
+ * fastest gr_fir for your platform.
+ *
+ * This is used internally by gr_fir_util.
+ */
+
+class gr_fir_sysconfig {
+public:
+ virtual ~gr_fir_sysconfig ();
+
+''')
+
+ for sig in fir_signatures:
+ out.write ((' virtual gr_fir_%s *create_gr_fir_%s (const std::vector<%s> &taps) = 0;\n' %
+ (sig, sig, tap_type (sig))))
+
+ out.write ('\n')
+
+ for sig in fir_signatures:
+ out.write ((' virtual void get_gr_fir_%s_info (std::vector<gr_fir_%s_info> *info) = 0;\n' %
+ (sig, sig)))
+
+ out.write (
+'''
+};
+
+/*
+ * This returns the single instance of the appropriate derived class.
+ * This function must be defined only once in the system, and should be defined
+ * in the platform specific code.
+ */
+
+gr_fir_sysconfig *gr_fir_sysconfig_singleton ();
+
+
+#endif /* INCLUDED_GR_FIR_SYSCONFIG_H */
+''')
+ out.close ()
+
+
+# ----------------------------------------------------------------
+
+def make_gr_fir_sysconfig_cc ():
+ out = open_and_log_name ('gr_fir_sysconfig.cc', 'w')
+ out.write (copyright)
+
+ out.write (
+'''
+/*
+ * WARNING: This file is automatically generated by generate_gr_fir_sysconfig.py
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_sysconfig.h>
+
+gr_fir_sysconfig::~gr_fir_sysconfig ()
+{
+}
+''')
+ out.close ()
+
+
+# ----------------------------------------------------------------
+
+def generate ():
+ make_gr_fir_sysconfig_h ()
+ make_gr_fir_sysconfig_cc ()
+
+if __name__ == '__main__':
+ generate ()
diff --git a/gnuradio-core/src/lib/filter/generate_gr_fir_sysconfig_generic.py b/gnuradio-core/src/lib/filter/generate_gr_fir_sysconfig_generic.py
new file mode 100755
index 0000000000..78cf3773cb
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/generate_gr_fir_sysconfig_generic.py
@@ -0,0 +1,182 @@
+#!/bin/env python
+# -*- python -*-
+#
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+from generate_utils import *
+
+
+# ----------------------------------------------------------------
+
+def make_gr_fir_sysconfig_generic_h ():
+ out = open_and_log_name ('gr_fir_sysconfig_generic.h', 'w')
+ out.write (copyright)
+
+ out.write (
+'''
+/*
+ * WARNING: This file is automatically generated by
+ * generate_gr_fir_sysconfig_generic.py.
+ *
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifndef _GR_FIR_SYSCONFIG_GENERIC_H_
+#define _GR_FIR_SYSCONFIG_GENERIC_H_
+
+#include <gr_fir_sysconfig.h>
+
+''')
+
+ out.write (
+'''
+class gr_fir_sysconfig_generic : public gr_fir_sysconfig {
+public:
+''')
+
+ for sig in fir_signatures:
+ out.write ((' virtual gr_fir_%s *create_gr_fir_%s (const std::vector<%s> &taps);\n' %
+ (sig, sig, tap_type (sig))))
+
+ out.write ('\n')
+
+ for sig in fir_signatures:
+ out.write ((' virtual void get_gr_fir_%s_info (std::vector<gr_fir_%s_info> *info);\n' %
+ (sig, sig)))
+
+ out.write (
+'''
+};
+
+
+#endif /* _GR_FIR_SYSCONFIG_GENERIC_H_ */
+''')
+ out.close ()
+
+
+# ----------------------------------------------------------------
+
+def make_constructor (sig, out):
+ out.write ('''
+static gr_fir_%s *
+make_gr_fir_%s (const std::vector<%s> &taps)
+{
+ return new gr_fir_%s_generic (taps);
+}
+''' % (sig, sig, tap_type (sig), sig))
+
+
+def make_creator (sig, out):
+ out.write ('''
+gr_fir_%s *
+gr_fir_sysconfig_generic::create_gr_fir_%s (const std::vector<%s> &taps)
+{
+ return make_gr_fir_%s (taps);
+}
+''' % (sig, sig, tap_type (sig), sig))
+
+
+def make_info (sig, out):
+ out.write ('''
+void
+gr_fir_sysconfig_generic::get_gr_fir_%s_info (std::vector<gr_fir_%s_info> *info)
+{
+ info->resize (1);
+ (*info)[0].name = "generic";
+ (*info)[0].create = make_gr_fir_%s;
+}
+''' % (sig, sig, sig))
+
+
+# ----------------------------------------------------------------
+
+def make_gr_fir_sysconfig_generic_cc ():
+ out = open_and_log_name ('gr_fir_sysconfig_generic.cc', 'w')
+ out.write (copyright)
+
+ out.write (
+'''
+/*
+ * WARNING: This file is automatically generated by
+ * generate_gr_fir_sysconfig_generic.py.
+ *
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_sysconfig_generic.h>
+
+''')
+
+ for sig in fir_signatures:
+ out.write ('#include <gr_fir_%s_generic.h>\n' % (sig))
+
+ out.write (
+'''
+/*
+ * ----------------------------------------------------------------
+ * static functions that serve as constructors returned by info
+ * ----------------------------------------------------------------
+ */
+''')
+
+ for sig in fir_signatures:
+ make_constructor (sig, out)
+
+ out.write (
+'''
+/*
+ * ----------------------------------------------------------------
+ * return instances of the generic C++ versions of these classes.
+ * ----------------------------------------------------------------
+ */
+''')
+
+ for sig in fir_signatures:
+ make_creator (sig, out)
+
+ out.write (
+'''
+/*
+ * Return info about available implementations.
+ *
+ * This is the bottom of the concrete hierarchy, so we set the
+ * size of the vector to 1, and install our info. Classes derived
+ * from us invoke us first, then append their own info.
+ */
+''')
+
+ for sig in fir_signatures:
+ make_info (sig, out)
+
+
+ out.close ()
+
+# ----------------------------------------------------------------
+
+def generate ():
+ make_gr_fir_sysconfig_generic_h ()
+ make_gr_fir_sysconfig_generic_cc ()
+
+if __name__ == '__main__':
+ generate ()
diff --git a/gnuradio-core/src/lib/filter/generate_gr_fir_util.py b/gnuradio-core/src/lib/filter/generate_gr_fir_util.py
new file mode 100755
index 0000000000..80d91863bb
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/generate_gr_fir_util.py
@@ -0,0 +1,185 @@
+#!/bin/env python
+#
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+from generate_utils import *
+
+def make_info_struct (out, sig):
+ out.write (
+'''
+struct gr_fir_%s_info {
+ const char *name; // implementation name, e.g., "generic", "SSE", "3DNow!"
+ gr_fir_%s *(*create)(const std::vector<%s> &taps);
+};
+''' % (sig, sig, tap_type(sig)))
+
+def make_create (out, sig):
+ out.write (''' static gr_fir_%s *create_gr_fir_%s (const std::vector<%s> &taps);
+''' % (sig, sig, tap_type (sig)))
+
+def make_info (out, sig):
+ out.write (''' static void get_gr_fir_%s_info (std::vector<gr_fir_%s_info> *info);
+''' % (sig, sig))
+
+
+# ----------------------------------------------------------------
+
+def make_gr_fir_util_h ():
+ out = open_and_log_name ('gr_fir_util.h', 'w')
+ out.write (copyright)
+
+ out.write (
+'''
+/*
+ * WARNING: This file is automatically generated by
+ * generate_gr_fir_util.py.
+ *
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifndef INCLUDED_GR_FIR_UTIL_H
+#define INCLUDED_GR_FIR_UTIL_H
+
+/*!
+ * \\brief routines to create gr_fir_XXX's
+ *
+ * This class handles selecting the fastest version of the finite
+ * implulse response filter available for your platform. This
+ * interface should be used by the rest of the system for creating
+ * gr_fir_XXX's.
+ *
+ * The trailing suffix has the form _IOT where I codes the input type,
+ * O codes the output type, and T codes the tap type.
+ * I,O,T are elements of the set 's' (short), 'f' (float), 'c' (gr_complex),
+ * 'i' (short)
+ */
+
+#include <gr_types.h>
+
+''')
+
+ for sig in fir_signatures:
+ out.write ('class gr_fir_%s;\n' % sig);
+
+ out.write ('\n// structures returned by get_gr_fir_XXX_info methods\n\n')
+
+ for sig in fir_signatures:
+ make_info_struct (out, sig)
+
+ out.write ('''
+struct gr_fir_util {
+
+ // create a fast version of gr_fir_XXX.
+
+''')
+
+ for sig in fir_signatures:
+ make_create (out, sig)
+
+ out.write ('''
+ // Get information about all gr_fir_XXX implementations.
+ // This is useful for benchmarking, testing, etc without having to
+ // know a priori what's linked into this image
+ //
+ // The caller must pass in a valid pointer to a vector.
+ // The vector will be filled with structs describing the
+ // available implementations.
+
+''')
+
+ for sig in fir_signatures:
+ make_info (out, sig)
+
+ out.write ('''
+};
+
+#endif /* INCLUDED_GR_FIR_UTIL_H */
+''')
+ out.close ()
+
+
+# ----------------------------------------------------------------
+
+def make_constructor_cc (out, sig):
+ out.write (
+'''
+gr_fir_%s *
+gr_fir_util::create_gr_fir_%s (const std::vector<%s> &taps)
+{
+ return gr_fir_sysconfig_singleton()->create_gr_fir_%s (taps);
+}
+''' % (sig, sig, tap_type (sig), sig))
+
+
+def make_info_cc (out, sig):
+ out.write (
+'''
+void
+gr_fir_util::get_gr_fir_%s_info (std::vector<gr_fir_%s_info> *info)
+{
+ gr_fir_sysconfig_singleton()->get_gr_fir_%s_info (info);
+}
+''' % (sig, sig, sig))
+
+
+def make_gr_fir_util_cc ():
+ out = open_and_log_name ('gr_fir_util.cc', 'w')
+ out.write (copyright)
+ out.write ('''
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_util.h>
+#include <gr_fir_sysconfig.h>
+
+//
+// There's no problem that can't be solved by the addition of
+// another layer of indirection...
+//
+
+// --- constructors ---
+
+''')
+
+ for sig in fir_signatures:
+ make_constructor_cc (out, sig)
+
+ out.write ('''
+// --- info gatherers ---
+
+''')
+
+ for sig in fir_signatures:
+ make_info_cc (out, sig)
+
+ out.close ()
+
+
+# ----------------------------------------------------------------
+
+def generate ():
+ make_gr_fir_util_h ()
+ make_gr_fir_util_cc ()
+
+if __name__ == '__main__':
+ generate ()
+
diff --git a/gnuradio-core/src/lib/filter/generate_gr_freq_xlating_fir_filter_XXX.py b/gnuradio-core/src/lib/filter/generate_gr_freq_xlating_fir_filter_XXX.py
new file mode 100755
index 0000000000..4a34556fd1
--- /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 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+import re
+from generate_utils import *
+
+# files to generate
+
+fx_signatures = [ 'scf', 'scc', 'fcf', 'fcc', 'ccf', 'ccc' ]
+
+roots = ['gr_freq_xlating_fir_filter_XXX']
+
+def expand_h_cc_i (root, code3):
+ d = init_dict (root, code3)
+ expand_template (d, root + '.h.t')
+ expand_template (d, root + '.cc.t')
+ expand_template (d, root + '.i.t')
+
+def init_dict (root, code3):
+ name = re.sub ('X+', code3, root)
+ d = standard_dict (name, code3)
+ d['FIR_TYPE'] = 'gr_fir_' + i_code (code3) + 'cc'
+ return d
+
+
+def generate ():
+ for r in roots:
+ for s in fx_signatures:
+ expand_h_cc_i (r, s)
+
+
+if __name__ == '__main__':
+ generate ()
diff --git a/gnuradio-core/src/lib/filter/generate_gr_interp_fir_filter_XXX.py b/gnuradio-core/src/lib/filter/generate_gr_interp_fir_filter_XXX.py
new file mode 100644
index 0000000000..00b3c7889b
--- /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 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+import re
+from generate_utils import *
+
+roots = ['gr_interp_fir_filter_XXX']
+
+def expand_h_cc_i (root, code3):
+ d = init_dict (root, code3)
+ expand_template (d, root + '.h.t')
+ expand_template (d, root + '.cc.t')
+ expand_template (d, root + '.i.t')
+
+def init_dict (root, code3):
+ name = re.sub ('X+', code3, root)
+ d = standard_dict (name, code3)
+ d['FIR_TYPE'] = 'gr_fir_' + code3
+ return d
+
+def generate ():
+ for r in roots:
+ for s in fir_signatures:
+ expand_h_cc_i (r, s)
+
+if __name__ == '__main__':
+ generate ()
+
diff --git a/gnuradio-core/src/lib/filter/generate_gr_rational_resampler_base_XXX.py b/gnuradio-core/src/lib/filter/generate_gr_rational_resampler_base_XXX.py
new file mode 100644
index 0000000000..0f96451a38
--- /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 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+import re
+from generate_utils import *
+
+roots = ['gr_rational_resampler_base_XXX']
+
+def expand_h_cc_i (root, code3):
+ d = init_dict (root, code3)
+ expand_template (d, root + '.h.t')
+ expand_template (d, root + '.cc.t')
+ expand_template (d, root + '.i.t')
+
+def init_dict (root, code3):
+ name = re.sub ('X+', code3, root)
+ d = standard_dict (name, code3)
+ d['FIR_TYPE'] = 'gr_fir_' + code3
+ return d
+
+def generate ():
+ for r in roots:
+ for s in fir_signatures:
+ expand_h_cc_i (r, s)
+
+if __name__ == '__main__':
+ generate ()
+
diff --git a/gnuradio-core/src/lib/filter/generate_utils.py b/gnuradio-core/src/lib/filter/generate_utils.py
new file mode 100644
index 0000000000..2eeb38e779
--- /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 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+## -----------------------------------------------------------------------
+## signatures defines which variations to generate (input, output, taps)
+
+fir_signatures = [ 'ccf', 'fcc', 'ccc', 'fff', 'scc', 'fsf' ]
+
+
+## -----------------------------------------------------------------------
+
+from build_utils import expand_template, copyright, open_and_log_name, standard_dict
+from build_utils_codes import *
diff --git a/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccf.cc b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccf.cc
new file mode 100644
index 0000000000..f2ab319bf2
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_adaptive_fir_ccf.h>
+#include <gr_io_signature.h>
+
+gr_adaptive_fir_ccf::gr_adaptive_fir_ccf(char *name, int decimation, const std::vector<float> &taps)
+ : gr_sync_decimator (name,
+ gr_make_io_signature (1, 1, sizeof(gr_complex)),
+ gr_make_io_signature (1, 1, sizeof(gr_complex)),
+ decimation),
+ d_updated(false)
+{
+ d_taps = taps;
+ set_history(d_taps.size());
+}
+
+void gr_adaptive_fir_ccf::set_taps(const std::vector<float> &taps)
+{
+ d_new_taps = taps;
+ d_updated = true;
+}
+
+int gr_adaptive_fir_ccf::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ gr_complex *in = (gr_complex *)input_items[0];
+ gr_complex *out = (gr_complex *)output_items[0];
+
+ if (d_updated) {
+ d_taps = d_new_taps;
+ set_history(d_taps.size());
+ d_updated = false;
+ return 0; // history requirements may have changed.
+ }
+
+ int j = 0, k, l = d_taps.size();
+ for (int i = 0; i < noutput_items; i++) {
+ // Generic dot product of d_taps[] and in[]
+ gr_complex sum(0.0, 0.0);
+ for (k = 0; k < l; k++)
+ sum += d_taps[l-k-1]*in[j+k];
+ out[i] = sum;
+
+ // Adjust taps
+ d_error = error(sum);
+ for (k = 0; k < l; k++) {
+ //printf("%f ", d_taps[k]);
+ update_tap(d_taps[l-k-1], in[j+k]);
+ }
+ //printf("\n");
+
+ j += decimation();
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccf.h b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccf.h
new file mode 100644
index 0000000000..57a95a3339
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccf.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_ADAPTIVE_FIR_CCF_H
+#define INCLUDED_GR_ADAPTIVE_FIR_CCF_H
+
+#include <gr_sync_decimator.h>
+
+/*!
+ * \brief Adaptive FIR filter with gr_complex input, gr_complex output and float taps
+ * \ingroup filter
+ */
+class gr_adaptive_fir_ccf : public gr_sync_decimator
+{
+private:
+ std::vector<float> d_new_taps;
+ bool d_updated;
+
+protected:
+ float d_error;
+ std::vector<float> d_taps;
+
+ // Override to calculate error signal per output
+ virtual float error(const gr_complex &out) = 0;
+
+ // Override to calculate new weight from old, corresponding input
+ virtual void update_tap(float &tap, const gr_complex &in) = 0;
+
+public:
+ gr_adaptive_fir_ccf(char *name, int decimation, const std::vector<float> &taps);
+ void set_taps(const std::vector<float> &taps);
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccf.i b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccf.i
new file mode 100644
index 0000000000..896fb42c7b
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+class gr_adaptive_fir_ccf : public gr_sync_decimator
+{
+private:
+ gr_adaptive_fir_ccf(char *name, int decimation, const std::vector<float> &taps);
+
+public:
+ void set_taps(const std::vector<float> &taps);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.cc b/gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.cc
new file mode 100644
index 0000000000..29b8a3e40d
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.cc
@@ -0,0 +1,41 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_cma_equalizer_cc.h>
+
+gr_cma_equalizer_cc_sptr
+gr_make_cma_equalizer_cc(int num_taps, float modulus, float mu)
+{
+ return gr_cma_equalizer_cc_sptr(new gr_cma_equalizer_cc(num_taps, modulus, mu));
+}
+
+gr_cma_equalizer_cc::gr_cma_equalizer_cc(int num_taps, float modulus, float mu)
+ : gr_adaptive_fir_ccf("cma_equalizer_cc", 1, std::vector<float>(num_taps)),
+ d_modulus(modulus), d_mu(mu)
+{
+ d_taps[0] = 1.0;
+}
+
diff --git a/gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.h b/gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.h
new file mode 100644
index 0000000000..25c996893d
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_CMA_EQUALIZER_CC_H
+#define INCLUDED_GR_CMA_EQUALIZER_CC_H
+
+#include <gr_adaptive_fir_ccf.h>
+
+class gr_cma_equalizer_cc;
+typedef boost::shared_ptr<gr_cma_equalizer_cc> gr_cma_equalizer_cc_sptr;
+
+gr_cma_equalizer_cc_sptr
+gr_make_cma_equalizer_cc(int num_taps, float modulus, float mu);
+
+/*!
+ * \brief Implements constant modulus adaptive filter on complex stream
+ * \ingroup filter
+ */
+class gr_cma_equalizer_cc : public gr_adaptive_fir_ccf
+{
+private:
+ float d_modulus;
+ float d_mu;
+
+ friend gr_cma_equalizer_cc_sptr gr_make_cma_equalizer_cc(int num_taps, float modulus, float mu);
+ gr_cma_equalizer_cc(int num_taps, float modulus, float mu);
+
+protected:
+
+ virtual float error(const gr_complex &out)
+ {
+ return (d_modulus - norm(out));
+ }
+
+ virtual void update_tap(float &tap, const gr_complex &in)
+ {
+ tap += d_mu*d_error*abs(in);
+ }
+
+public:
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.i b/gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.i
new file mode 100644
index 0000000000..c64bfc3a09
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_cma_equalizer_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,cma_equalizer_cc)
+
+%include <gr_adaptive_fir_ccf.i>
+
+gr_cma_equalizer_cc_sptr gr_make_cma_equalizer_cc(int num_taps, float modulus, float mu);
+
+class gr_cma_equalizer_cc : public gr_adaptive_fir_ccf
+{
+private:
+ gr_cma_equalizer_cc(int num_taps, float modulus, float mu);
+
+public:
+};
diff --git a/gnuradio-core/src/lib/filter/gr_cpu.cc b/gnuradio-core/src/lib/filter/gr_cpu.cc
new file mode 100644
index 0000000000..7e926f34a9
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_cpu.cc
@@ -0,0 +1,107 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gr_cpu.h>
+
+/*
+ * execute CPUID instruction, return EAX, EBX, ECX and EDX values in result
+ */
+extern "C" {
+void cpuid_x86 (unsigned int op, unsigned int result[4]);
+};
+
+/*
+ * CPUID functions returning a single datum
+ */
+
+static inline unsigned int cpuid_eax(unsigned int op)
+{
+ unsigned int regs[4];
+ cpuid_x86 (op, regs);
+ return regs[0];
+}
+
+static inline unsigned int cpuid_ebx(unsigned int op)
+{
+ unsigned int regs[4];
+ cpuid_x86 (op, regs);
+ return regs[1];
+}
+
+static inline unsigned int cpuid_ecx(unsigned int op)
+{
+ unsigned int regs[4];
+ cpuid_x86 (op, regs);
+ return regs[2];
+}
+
+static inline unsigned int cpuid_edx(unsigned int op)
+{
+ unsigned int regs[4];
+ cpuid_x86 (op, regs);
+ return regs[3];
+}
+
+// ----------------------------------------------------------------
+
+bool
+gr_cpu::has_mmx ()
+{
+ unsigned int edx = cpuid_edx (1); // standard features
+ return (edx & (1 << 23)) != 0;
+}
+
+bool
+gr_cpu::has_sse ()
+{
+ unsigned int edx = cpuid_edx (1); // standard features
+ return (edx & (1 << 25)) != 0;
+}
+
+bool
+gr_cpu::has_sse2 ()
+{
+ unsigned int edx = cpuid_edx (1); // standard features
+ return (edx & (1 << 26)) != 0;
+}
+
+bool
+gr_cpu::has_3dnow ()
+{
+ unsigned int extended_fct_count = cpuid_eax (0x80000000);
+ if (extended_fct_count < 0x80000001)
+ return false;
+
+ unsigned int extended_features = cpuid_edx (0x80000001);
+ return (extended_features & (1 << 31)) != 0;
+}
+
+bool
+gr_cpu::has_3dnowext ()
+{
+ unsigned int extended_fct_count = cpuid_eax (0x80000000);
+ if (extended_fct_count < 0x80000001)
+ return false;
+
+ unsigned int extended_features = cpuid_edx (0x80000001);
+ return (extended_features & (1 << 30)) != 0;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_cpu.h b/gnuradio-core/src/lib/filter/gr_cpu.h
new file mode 100644
index 0000000000..563b60cb17
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_cpu.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GR_CPU_H_
+#define _GR_CPU_H_
+
+struct gr_cpu {
+ static bool has_mmx ();
+ static bool has_sse ();
+ static bool has_sse2 ();
+ static bool has_3dnow ();
+ static bool has_3dnowext ();
+};
+
+#endif /* _GR_CPU_H_ */
diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.cc b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.cc
new file mode 100644
index 0000000000..c90e3a0f42
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.cc
@@ -0,0 +1,210 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * WARNING: This file is automatically generated by generate_gr_fft_filter_XXX.py
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_fft_filter_ccc.h>
+#include <gr_io_signature.h>
+#include <gri_fft.h>
+#include <math.h>
+#include <assert.h>
+#include <stdexcept>
+#include <gr_firdes.h>
+
+#include <iostream>
+
+gr_fft_filter_ccc_sptr gr_make_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps)
+{
+ return gr_fft_filter_ccc_sptr (new gr_fft_filter_ccc (decimation, taps));
+}
+
+
+gr_fft_filter_ccc::gr_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps)
+ : gr_sync_decimator ("fft_filter_ccc",
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ decimation),
+ d_fftsize(-1), d_fwdfft(0), d_invfft(0), d_updated(false)
+{
+ // if (decimation != 1)
+ // throw std::invalid_argument("gr_fft_filter_ccc: decimation must be 1");
+
+ set_history(1);
+ actual_set_taps(taps);
+}
+
+gr_fft_filter_ccc::~gr_fft_filter_ccc ()
+{
+ delete d_fwdfft;
+ delete d_invfft;
+}
+
+static void
+print_vector_complex(const std::string label, const std::vector<gr_complex> &x)
+{
+ std::cout << label;
+ for (unsigned i = 0; i < x.size(); i++)
+ std::cout << x[i] << " ";
+ std::cout << "\n";
+}
+
+void
+gr_fft_filter_ccc::set_taps (const std::vector<gr_complex> &taps)
+{
+ d_new_taps = taps;
+ d_updated = true;
+}
+
+/*
+ * determines d_ntaps, d_nsamples, d_fftsize, d_xformed_taps
+ */
+void
+gr_fft_filter_ccc::actual_set_taps (const std::vector<gr_complex> &taps)
+{
+ int i = 0;
+ compute_sizes(taps.size());
+
+ d_tail.resize(tailsize());
+ for (i = 0; i < tailsize(); i++)
+ d_tail[i] = 0;
+
+ gr_complex *in = d_fwdfft->get_inbuf();
+ gr_complex *out = d_fwdfft->get_outbuf();
+
+ float scale = 1.0 / d_fftsize;
+
+ // Compute forward xform of taps.
+ // Copy taps into first ntaps slots, then pad with zeros
+ for (i = 0; i < d_ntaps; i++)
+ in[i] = taps[i] * scale;
+
+ for (; i < d_fftsize; i++)
+ in[i] = 0;
+
+ d_fwdfft->execute(); // do the xform
+
+ // now copy output to d_xformed_taps
+ for (i = 0; i < d_fftsize; i++)
+ d_xformed_taps[i] = out[i];
+
+ //print_vector_complex("transformed taps:", d_xformed_taps);
+}
+
+// determine and set d_ntaps, d_nsamples, d_fftsize
+
+void
+gr_fft_filter_ccc::compute_sizes(int ntaps)
+{
+ int old_fftsize = d_fftsize;
+ d_ntaps = ntaps;
+ d_fftsize = (int) (2 * pow(2.0, ceil(log(ntaps) / log(2))));
+ d_nsamples = d_fftsize - d_ntaps + 1;
+
+ if (0)
+ fprintf(stderr, "gr_fft_filter: ntaps = %d, fftsize = %d, nsamples = %d\n",
+ d_ntaps, d_fftsize, d_nsamples);
+
+ assert(d_fftsize == d_ntaps + d_nsamples -1 );
+
+ if (d_fftsize != old_fftsize){ // compute new plans
+ delete d_fwdfft;
+ delete d_invfft;
+ d_fwdfft = new gri_fft_complex(d_fftsize, true);
+ d_invfft = new gri_fft_complex(d_fftsize, false);
+ d_xformed_taps.resize(d_fftsize);
+ }
+
+ set_output_multiple(d_nsamples);
+}
+
+int
+gr_fft_filter_ccc::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ gr_complex *in = (gr_complex *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ if (d_updated){
+ actual_set_taps(d_new_taps);
+ d_updated = false;
+ return 0; // output multiple may have changed
+ }
+
+ assert(noutput_items % d_nsamples == 0);
+
+ int dec_ctr = 0;
+ int j = 0;
+ int ninput_items = noutput_items * decimation();
+
+ for (int i = 0; i < ninput_items; i += d_nsamples){
+
+ memcpy(d_fwdfft->get_inbuf(), &in[i], d_nsamples * sizeof(gr_complex));
+
+ for (j = d_nsamples; j < d_fftsize; j++)
+ d_fwdfft->get_inbuf()[j] = 0;
+
+ d_fwdfft->execute(); // compute fwd xform
+
+ gr_complex *a = d_fwdfft->get_outbuf();
+ gr_complex *b = &d_xformed_taps[0];
+ gr_complex *c = d_invfft->get_inbuf();
+
+ for (j = 0; j < d_fftsize; j++) // filter in the freq domain
+ c[j] = a[j] * b[j];
+
+ d_invfft->execute(); // compute inv xform
+
+ // add in the overlapping tail
+
+ for (j = 0; j < tailsize(); j++)
+ d_invfft->get_outbuf()[j] += d_tail[j];
+
+ // copy nsamples to output
+
+ //memcpy(out, d_invfft->get_outbuf(), d_nsamples * sizeof(gr_complex));
+ //out += d_nsamples;
+
+ j = dec_ctr;
+ while (j < d_nsamples) {
+ *out++ = d_invfft->get_outbuf()[j];
+ j += decimation();
+ }
+ dec_ctr = (j - d_nsamples);
+
+ // stash the tail
+ memcpy(&d_tail[0], d_invfft->get_outbuf() + d_nsamples,
+ tailsize() * sizeof(gr_complex));
+ }
+
+ assert((out - (gr_complex *) output_items[0]) == noutput_items);
+ assert(dec_ctr == 0);
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.h b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.h
new file mode 100644
index 0000000000..06bc7c1b94
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.h
@@ -0,0 +1,77 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_FFT_FILTER_CCC_H
+#define INCLUDED_GR_FFT_FILTER_CCC_H
+
+#include <gr_sync_decimator.h>
+
+class gr_fft_filter_ccc;
+typedef boost::shared_ptr<gr_fft_filter_ccc> gr_fft_filter_ccc_sptr;
+gr_fft_filter_ccc_sptr gr_make_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps);
+
+class gr_fir_ccc;
+class gri_fft_complex;
+
+/*!
+ * \brief Fast FFT filter with gr_complex input, gr_complex output and gr_complex taps
+ * \ingroup filter
+ */
+class gr_fft_filter_ccc : public gr_sync_decimator
+{
+ private:
+ friend gr_fft_filter_ccc_sptr gr_make_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps);
+
+ int d_ntaps;
+ int d_nsamples;
+ int d_fftsize; // fftsize = ntaps + nsamples - 1
+ gri_fft_complex *d_fwdfft; // forward "plan"
+ gri_fft_complex *d_invfft; // inverse "plan"
+ std::vector<gr_complex> d_tail; // state carried between blocks for overlap-add
+ std::vector<gr_complex> d_xformed_taps; // Fourier xformed taps
+ std::vector<gr_complex> d_new_taps;
+ bool d_updated;
+
+ /*!
+ * Construct a FFT filter with the given taps
+ *
+ * \param decimation >= 1
+ * \param taps complex filter taps
+ */
+ gr_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps);
+
+ void compute_sizes(int ntaps);
+ int tailsize() const { return d_ntaps - 1; }
+ void actual_set_taps (const std::vector<gr_complex> &taps);
+
+ public:
+ ~gr_fft_filter_ccc ();
+
+ void set_taps (const std::vector<gr_complex> &taps);
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+
+#endif /* INCLUDED_GR_FFT_FILTER_CCC_H */
diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.i b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.i
new file mode 100644
index 0000000000..65cbb3627a
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.i
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,fft_filter_ccc)
+
+gr_fft_filter_ccc_sptr
+gr_make_fft_filter_ccc (int decimation,
+ const std::vector<gr_complex> &taps
+ ) throw (std::invalid_argument);
+
+class gr_fft_filter_ccc : public gr_sync_decimator
+{
+ private:
+ gr_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps);
+
+ public:
+ ~gr_fft_filter_ccc ();
+
+ void set_taps (const std::vector<gr_complex> &taps);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_fff.cc b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.cc
new file mode 100644
index 0000000000..ceb2e8284b
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.cc
@@ -0,0 +1,211 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_fft_filter_fff.h>
+#include <gr_io_signature.h>
+#include <gri_fft.h>
+#include <math.h>
+#include <assert.h>
+#include <stdexcept>
+#include <gr_firdes.h>
+
+#include <iostream>
+
+gr_fft_filter_fff_sptr gr_make_fft_filter_fff (int decimation, const std::vector<float> &taps)
+{
+ return gr_fft_filter_fff_sptr (new gr_fft_filter_fff (decimation, taps));
+}
+
+
+gr_fft_filter_fff::gr_fft_filter_fff (int decimation, const std::vector<float> &taps)
+ : gr_sync_decimator ("fft_filter_fff",
+ gr_make_io_signature (1, 1, sizeof (float)),
+ gr_make_io_signature (1, 1, sizeof (float)),
+ decimation),
+ d_fftsize(-1), d_fwdfft(0), d_invfft(0), d_updated(false)
+{
+ set_history(1);
+ actual_set_taps(taps);
+}
+
+gr_fft_filter_fff::~gr_fft_filter_fff ()
+{
+ delete d_fwdfft;
+ delete d_invfft;
+}
+
+static void
+print_vector_complex(const std::string label, const std::vector<gr_complex> &x)
+{
+ std::cout << label;
+ for (unsigned i = 0; i < x.size(); i++)
+ std::cout << x[i] << " ";
+ std::cout << "\n";
+}
+
+static void
+print_vector_float(const std::string label, const std::vector<float> &x)
+{
+ std::cout << label;
+ for (unsigned i = 0; i < x.size(); i++)
+ std::cout << x[i] << " ";
+ std::cout << "\n";
+}
+
+void
+gr_fft_filter_fff::set_taps (const std::vector<float> &taps)
+{
+ d_new_taps = taps;
+ d_updated = true;
+}
+
+/*
+ * determines d_ntaps, d_nsamples, d_fftsize, d_xformed_taps
+ */
+void
+gr_fft_filter_fff::actual_set_taps (const std::vector<float> &taps)
+{
+ int i = 0;
+ compute_sizes(taps.size());
+
+ d_tail.resize(tailsize());
+ for (i = 0; i < tailsize(); i++)
+ d_tail[i] = 0;
+
+ float *in = d_fwdfft->get_inbuf();
+ gr_complex *out = d_fwdfft->get_outbuf();
+
+ float scale = 1.0 / d_fftsize;
+
+ // Compute forward xform of taps.
+ // Copy taps into first ntaps slots, then pad with zeros
+ for (i = 0; i < d_ntaps; i++)
+ in[i] = taps[i] * scale;
+
+ for (; i < d_fftsize; i++)
+ in[i] = 0;
+
+ d_fwdfft->execute(); // do the xform
+
+ // now copy output to d_xformed_taps
+ for (i = 0; i < d_fftsize/2+1; i++)
+ d_xformed_taps[i] = out[i];
+
+ //print_vector_complex("transformed taps:", d_xformed_taps);
+}
+
+// determine and set d_ntaps, d_nsamples, d_fftsize
+
+void
+gr_fft_filter_fff::compute_sizes(int ntaps)
+{
+ int old_fftsize = d_fftsize;
+ d_ntaps = ntaps;
+ d_fftsize = (int) (2 * pow(2.0, ceil(log(ntaps) / log(2))));
+ d_nsamples = d_fftsize - d_ntaps + 1;
+
+ if (0)
+ fprintf(stderr, "gr_fft_filter: ntaps = %d, fftsize = %d, nsamples = %d\n",
+ d_ntaps, d_fftsize, d_nsamples);
+
+ assert(d_fftsize == d_ntaps + d_nsamples -1 );
+
+ if (d_fftsize != old_fftsize){ // compute new plans
+ delete d_fwdfft;
+ delete d_invfft;
+ d_fwdfft = new gri_fft_real_fwd(d_fftsize);
+ d_invfft = new gri_fft_real_rev(d_fftsize);
+ d_xformed_taps.resize(d_fftsize/2+1);
+ }
+
+ set_output_multiple(d_nsamples);
+}
+
+int
+gr_fft_filter_fff::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+ float *out = (float *) output_items[0];
+
+ if (d_updated){
+ actual_set_taps(d_new_taps);
+ d_updated = false;
+ return 0; // output multiple may have changed
+ }
+
+ assert(noutput_items % d_nsamples == 0);
+
+ int dec_ctr = 0;
+ int j = 0;
+ int ninput_items = noutput_items * decimation();
+
+ for (int i = 0; i < ninput_items; i += d_nsamples){
+
+ memcpy(d_fwdfft->get_inbuf(), &in[i], d_nsamples * sizeof(float));
+
+ for (j = d_nsamples; j < d_fftsize; j++)
+ d_fwdfft->get_inbuf()[j] = 0;
+
+ d_fwdfft->execute(); // compute fwd xform
+
+ gr_complex *a = d_fwdfft->get_outbuf();
+ gr_complex *b = &d_xformed_taps[0];
+ gr_complex *c = d_invfft->get_inbuf();
+
+ for (j = 0; j < d_fftsize/2+1; j++) // filter in the freq domain
+ c[j] = a[j] * b[j];
+
+ d_invfft->execute(); // compute inv xform
+
+ // add in the overlapping tail
+
+ for (j = 0; j < tailsize(); j++)
+ d_invfft->get_outbuf()[j] += d_tail[j];
+
+ // copy nsamples to output
+
+ //memcpy(out, d_invfft->get_outbuf(), d_nsamples * sizeof(float));
+ //out += d_nsamples;
+
+ j = dec_ctr;
+ while (j < d_nsamples) {
+ *out++ = d_invfft->get_outbuf()[j];
+ j += decimation();
+ }
+ dec_ctr = (j - d_nsamples);
+
+ // stash the tail
+ memcpy(&d_tail[0], d_invfft->get_outbuf() + d_nsamples,
+ tailsize() * sizeof(float));
+ }
+
+ assert((out - (float *) output_items[0]) == noutput_items);
+ assert(dec_ctr == 0);
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_fff.h b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.h
new file mode 100644
index 0000000000..bdd29b7030
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.h
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_FFT_FILTER_FFF_H
+#define INCLUDED_GR_FFT_FILTER_FFF_H
+
+#include <gr_sync_decimator.h>
+
+class gr_fft_filter_fff;
+typedef boost::shared_ptr<gr_fft_filter_fff> gr_fft_filter_fff_sptr;
+gr_fft_filter_fff_sptr gr_make_fft_filter_fff (int decimation, const std::vector<float> &taps);
+
+class gr_fir_fff;
+class gri_fft_real_fwd;
+class gri_fft_real_rev;
+
+/*!
+ * \brief Fast FFT filter with float input, float output and float taps
+ * \ingroup filter
+ */
+class gr_fft_filter_fff : public gr_sync_decimator
+{
+ private:
+ friend gr_fft_filter_fff_sptr gr_make_fft_filter_fff (int decimation, const std::vector<float> &taps);
+
+ int d_ntaps;
+ int d_nsamples;
+ int d_fftsize; // fftsize = ntaps + nsamples - 1
+ gri_fft_real_fwd *d_fwdfft; // forward "plan"
+ gri_fft_real_rev *d_invfft; // inverse "plan"
+ std::vector<float> d_tail; // state carried between blocks for overlap-add
+ std::vector<gr_complex> d_xformed_taps; // Fourier xformed taps
+ std::vector<float> d_new_taps;
+ bool d_updated;
+
+ /*!
+ * Construct a FFT filter with the given taps
+ *
+ * \param decimation >= 1
+ * \param taps float filter taps
+ */
+ gr_fft_filter_fff (int decimation, const std::vector<float> &taps);
+
+ void compute_sizes(int ntaps);
+ int tailsize() const { return d_ntaps - 1; }
+ void actual_set_taps (const std::vector<float> &taps);
+
+ public:
+ ~gr_fft_filter_fff ();
+
+ void set_taps (const std::vector<float> &taps);
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_FFT_FILTER_FFF_H */
diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_fff.i b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.i
new file mode 100644
index 0000000000..5ee30ebbb3
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.i
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,fft_filter_fff)
+
+gr_fft_filter_fff_sptr
+gr_make_fft_filter_fff (int decimation,
+ const std::vector<float> &taps
+ ) throw (std::invalid_argument);
+
+class gr_fft_filter_fff : public gr_sync_decimator
+{
+ private:
+ gr_fft_filter_fff (int decimation, const std::vector<float> &taps);
+
+ public:
+ ~gr_fft_filter_fff ();
+
+ void set_taps (const std::vector<float> &taps);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_filter_delay_fc.cc b/gnuradio-core/src/lib/filter/gr_filter_delay_fc.cc
new file mode 100644
index 0000000000..09f181ea12
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_filter_delay_fc.cc
@@ -0,0 +1,80 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_filter_delay_fc.h>
+#include <gr_fir_fff.h>
+#include <gr_fir_util.h>
+
+// public constructor
+gr_filter_delay_fc_sptr
+gr_make_filter_delay_fc (const std::vector<float> &taps)
+{
+ return gr_filter_delay_fc_sptr (new gr_filter_delay_fc (taps));
+}
+
+gr_filter_delay_fc::gr_filter_delay_fc (const std::vector<float> &taps)
+ : gr_sync_block ("filter_delay_fc",
+ gr_make_io_signature (1, 2, sizeof (float)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex)))
+{
+ d_fir = gr_fir_util::create_gr_fir_fff (taps);
+ d_delay = d_fir->ntaps () / 2;
+ set_history (d_fir->ntaps ());
+}
+
+gr_filter_delay_fc::~gr_filter_delay_fc ()
+{
+ delete d_fir;
+}
+
+int
+gr_filter_delay_fc::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ float *in0 = (float *) input_items[0];
+ float *in1 = (float *) input_items[1];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ switch (input_items.size ()){
+ case 1:
+ for (int i = 0; i < noutput_items; i++)
+ out[i] = gr_complex (in0[i + d_delay],
+ d_fir->filter (&in0[i]));
+ break;
+
+ case 2:
+ for (int j = 0; j < noutput_items; j++)
+ out[j] = gr_complex (in0[j + d_delay],
+ d_fir->filter (&in1[j]));
+ break;
+
+ default:
+ assert (0);
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_filter_delay_fc.h b/gnuradio-core/src/lib/filter/gr_filter_delay_fc.h
new file mode 100644
index 0000000000..2b65c67233
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_filter_delay_fc.h
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_FILTER_DELAY_FC_H
+#define INCLUDED_GR_FILTER_DELAY_FC_H
+
+#include <gr_sync_block.h>
+#include <gr_io_signature.h>
+#include <gr_types.h>
+
+class gr_filter_delay_fc;
+typedef boost::shared_ptr<gr_filter_delay_fc> gr_filter_delay_fc_sptr;
+
+// public constructor
+gr_filter_delay_fc_sptr gr_make_filter_delay_fc (const std::vector<float> &taps);
+
+class gr_fir_fff;
+
+/*!
+ * \brief Filter-Delay Combination Block.
+ * \ingroup filter
+ *
+ * The block takes one or two float stream and outputs a complex
+ * stream. If only one float stream is input, the real output is
+ * a delayed version of this input and the imaginary output is the
+ * filtered output. If two floats are connected to the input, then
+ * the real output is the delayed version of the first input, and
+ * the imaginary output is the filtered output. The delay in the
+ * real path accounts for the group delay introduced by the filter
+ * in the imaginary path. The filter taps needs to be calculated
+ * before initializing this block.
+ *
+ */
+class gr_filter_delay_fc : public gr_sync_block
+{
+ public:
+ ~gr_filter_delay_fc ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ protected:
+ gr_filter_delay_fc (const std::vector<float> &taps);
+
+ private:
+ unsigned int d_delay;
+ gr_fir_fff *d_fir;
+
+ friend gr_filter_delay_fc_sptr gr_make_filter_delay_fc (const std::vector<float> &taps);
+};
+
+#endif /* INCLUDED_GR_FILTER_DELAY_FC_H */
diff --git a/gnuradio-core/src/lib/filter/gr_filter_delay_fc.i b/gnuradio-core/src/lib/filter/gr_filter_delay_fc.i
new file mode 100644
index 0000000000..85603ce22d
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,filter_delay_fc);
+
+gr_filter_delay_fc_sptr gr_make_filter_delay_fc (const std::vector<float> &taps);
+
+class gr_filter_delay_fc : public gr_sync_block
+{
+private:
+ gr_filter_delay_fc ();
+};
+
+// ----------------------------------------------------------------
+
diff --git a/gnuradio-core/src/lib/filter/gr_fir_XXX.cc.t b/gnuradio-core/src/lib/filter/gr_fir_XXX.cc.t
new file mode 100644
index 0000000000..1f7866229d
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <@FIR_TYPE@.h>
+
+@FIR_TYPE@::~@FIR_TYPE@ ()
+{
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_XXX.h.t b/gnuradio-core/src/lib/filter/gr_fir_XXX.h.t
new file mode 100644
index 0000000000..a5bf3ed035
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_XXX.h.t
@@ -0,0 +1,123 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * WARNING: This file is automatically generated by generate_gr_fir_XXX.py
+ * Any changes made to this file will be overwritten.
+ */
+
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <vector>
+@VRCOMPLEX_INCLUDE@
+#include <gr_reverse.h>
+
+/*!
+ * \brief Abstract class for FIR with @I_TYPE@ input, @O_TYPE@ output and @TAP_TYPE@ taps
+ * \ingroup filter_primitive
+ *
+ * This is the abstract class for a Finite Impulse Response filter.
+ *
+ * The trailing suffix has the form _IOT where I codes the input type,
+ * O codes the output type, and T codes the tap type.
+ * I,O,T are elements of the set 's' (short), 'f' (float), 'c' (gr_complex), 'i' (int)
+ */
+
+class @FIR_TYPE@ {
+
+protected:
+ std::vector<@TAP_TYPE@> d_taps; // reversed taps
+
+public:
+
+ // CONSTRUCTORS
+
+ /*!
+ * \brief construct new FIR with given taps.
+ *
+ * Note that taps must be in forward order, e.g., coefficient 0 is
+ * stored in new_taps[0], coefficient 1 is stored in
+ * new_taps[1], etc.
+ */
+ @FIR_TYPE@ () {}
+ @FIR_TYPE@ (const std::vector<@TAP_TYPE@> &taps) : d_taps (gr_reverse(taps)) {}
+
+ virtual ~@FIR_TYPE@ ();
+
+ // MANIPULATORS
+
+ /*!
+ * \brief compute a single output value.
+ *
+ * \p input must have ntaps() valid entries.
+ * input[0] .. input[ntaps() - 1] are referenced to compute the output value.
+ *
+ * \returns the filtered input value.
+ */
+ virtual @O_TYPE@ filter (const @I_TYPE@ input[]) = 0;
+
+ /*!
+ * \brief compute an array of N output values.
+ *
+ * \p input must have (n - 1 + ntaps()) valid entries.
+ * input[0] .. input[n - 1 + ntaps() - 1] are referenced to compute the output values.
+ */
+ virtual void filterN (@O_TYPE@ output[], const @I_TYPE@ input[],
+ unsigned long n) = 0;
+
+ /*!
+ * \brief compute an array of N output values, decimating the input
+ *
+ * \p input must have (decimate * (n - 1) + ntaps()) valid entries.
+ * input[0] .. input[decimate * (n - 1) + ntaps() - 1] are referenced to
+ * compute the output values.
+ */
+ virtual void filterNdec (@O_TYPE@ output[], const @I_TYPE@ input[],
+ unsigned long n, unsigned decimate) = 0;
+
+ /*!
+ * \brief install \p new_taps as the current taps.
+ */
+ virtual void set_taps (const std::vector<@TAP_TYPE@> &taps)
+ {
+ d_taps = gr_reverse(taps);
+ }
+
+ // ACCESSORS
+
+ /*!
+ * \return number of taps in filter.
+ */
+ unsigned ntaps () const { return d_taps.size (); }
+
+ /*!
+ * \return current taps
+ */
+ virtual const std::vector<@TAP_TYPE@> get_taps () const
+ {
+ return gr_reverse(d_taps);
+ }
+};
+
+#endif /* @GUARD_NAME@ */
diff --git a/gnuradio-core/src/lib/filter/gr_fir_XXX_generic.cc.t b/gnuradio-core/src/lib/filter/gr_fir_XXX_generic.cc.t
new file mode 100644
index 0000000000..7bc7a5eb2b
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <@FIR_TYPE@_generic.h>
+
+#if (@N_UNROLL@ == 4)
+
+@O_TYPE@
+@FIR_TYPE@_generic::filter (const @I_TYPE@ input[])
+{
+ static const int N_UNROLL = 4;
+
+ @ACC_TYPE@ acc0 = 0;
+ @ACC_TYPE@ acc1 = 0;
+ @ACC_TYPE@ acc2 = 0;
+ @ACC_TYPE@ acc3 = 0;
+
+
+ unsigned i = 0;
+ unsigned n = (ntaps () / N_UNROLL) * N_UNROLL;
+
+ for (i = 0; i < n; i += N_UNROLL){
+ acc0 += d_taps[i + 0] * @INPUT_CAST@ input[i + 0];
+ acc1 += d_taps[i + 1] * @INPUT_CAST@ input[i + 1];
+ acc2 += d_taps[i + 2] * @INPUT_CAST@ input[i + 2];
+ acc3 += d_taps[i + 3] * @INPUT_CAST@ input[i + 3];
+ }
+
+ for (; i < ntaps (); i++)
+ acc0 += d_taps[i] * @INPUT_CAST@ input[i];
+
+ return (@O_TYPE@) (acc0 + acc1 + acc2 + acc3);
+}
+
+#else
+
+@O_TYPE@
+@FIR_TYPE@_generic::filter (const @I_TYPE@ input[])
+{
+ static const int N_UNROLL = 2;
+
+ @ACC_TYPE@ acc0 = 0;
+ @ACC_TYPE@ acc1 = 0;
+
+ unsigned i = 0;
+ unsigned n = (ntaps () / N_UNROLL) * N_UNROLL;
+
+ for (i = 0; i < n; i += N_UNROLL){
+ acc0 += d_taps[i + 0] * @INPUT_CAST@ input[i + 0];
+ acc1 += d_taps[i + 1] * @INPUT_CAST@ input[i + 1];
+ }
+
+ for (; i < ntaps (); i++)
+ acc0 += d_taps[i] * @INPUT_CAST@ input[i];
+
+ return (@O_TYPE@) (acc0 + acc1);
+}
+
+#endif // N_UNROLL
+
+void
+@FIR_TYPE@_generic::filterN (@O_TYPE@ output[],
+ const @I_TYPE@ input[],
+ unsigned long n)
+{
+ for (unsigned i = 0; i < n; i++)
+ output[i] = filter (&input[i]);
+}
+
+void
+@FIR_TYPE@_generic::filterNdec (@O_TYPE@ output[],
+ const @I_TYPE@ input[],
+ unsigned long n,
+ unsigned decimate)
+{
+ unsigned j = 0;
+ for (unsigned i = 0; i < n; i++){
+ output[i] = filter (&input[j]);
+ j += decimate;
+ }
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_XXX_generic.h.t b/gnuradio-core/src/lib/filter/gr_fir_XXX_generic.h.t
new file mode 100644
index 0000000000..b1b2f4025f
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_XXX_generic.h.t
@@ -0,0 +1,77 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <@FIR_TYPE@.h>
+
+/*!
+ * \brief Concrete class for generic implementation of FIR with @I_TYPE@ input, @O_TYPE@ output and @TAP_TYPE@ taps
+ *
+ * The trailing suffix has the form _IOT where I codes the input type,
+ * O codes the output type, and T codes the tap type.
+ * I,O,T are elements of the set 's' (short), 'f' (float), 'c' (gr_complex), 'i' (int)
+ */
+
+class @FIR_TYPE@_generic : public @FIR_TYPE@ {
+
+public:
+
+ // CREATORS
+
+ @FIR_TYPE@_generic () {}
+ @FIR_TYPE@_generic (const std::vector<@TAP_TYPE@> &taps) : @FIR_TYPE@ (taps) {}
+
+ // MANIPULATORS
+
+ /*!
+ * \brief compute a single output value.
+ *
+ * \p input must have ntaps() valid entries.
+ * input[0] .. input[ntaps() - 1] are referenced to compute the output value.
+ *
+ * \returns the filtered input value.
+ */
+ virtual @O_TYPE@ filter (const @I_TYPE@ input[]);
+
+ /*!
+ * \brief compute an array of N output values.
+ *
+ * \p input must have (n - 1 + ntaps()) valid entries.
+ * input[0] .. input[n - 1 + ntaps() - 1] are referenced to compute the output values.
+ */
+ virtual void filterN (@O_TYPE@ output[], const @I_TYPE@ input[],
+ unsigned long n);
+
+ /*!
+ * \brief compute an array of N output values, decimating the input
+ *
+ * \p input must have (decimate * (n - 1) + ntaps()) valid entries.
+ * input[0] .. input[decimate * (n - 1) + ntaps() - 1] are referenced to
+ * compute the output values.
+ */
+ virtual void filterNdec (@O_TYPE@ output[], const @I_TYPE@ input[],
+ unsigned long n, unsigned decimate);
+
+};
+
+#endif /* @GUARD_NAME@ */
diff --git a/gnuradio-core/src/lib/filter/gr_fir_ccc_simd.cc b/gnuradio-core/src/lib/filter/gr_fir_ccc_simd.cc
new file mode 100644
index 0000000000..6d5cba3bde
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_ccc_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_ccc_simd.h>
+
+#include <assert.h>
+#include <malloc16.h>
+#include <iostream>
+
+using std::cerr;
+using std::endl;
+
+gr_fir_ccc_simd::gr_fir_ccc_simd ()
+ : gr_fir_ccc_generic ()
+{
+ // cerr << "@@@ gr_fir_ccc_simd\n";
+
+ d_ccomplex_dotprod = 0;
+
+ d_aligned_taps[0] = 0;
+ d_aligned_taps[1] = 0;
+ d_aligned_taps[2] = 0;
+ d_aligned_taps[3] = 0;
+}
+
+gr_fir_ccc_simd::gr_fir_ccc_simd (const std::vector<gr_complex> &new_taps)
+ : gr_fir_ccc_generic (new_taps)
+{
+ // cerr << "@@@ gr_fir_ccc_simd\n";
+
+ d_ccomplex_dotprod = 0;
+
+ d_aligned_taps[0] = 0;
+ d_aligned_taps[1] = 0;
+ d_aligned_taps[2] = 0;
+ d_aligned_taps[3] = 0;
+ set_taps (new_taps);
+}
+
+gr_fir_ccc_simd::~gr_fir_ccc_simd ()
+{
+ free16Align (d_aligned_taps[0]);
+ free16Align (d_aligned_taps[1]);
+ free16Align (d_aligned_taps[2]);
+ free16Align (d_aligned_taps[3]);
+}
+
+void
+gr_fir_ccc_simd::set_taps (const std::vector<gr_complex> &inew_taps)
+{
+ gr_fir_ccc::set_taps (inew_taps); // call superclass
+
+ const std::vector<gr_complex> new_taps = gr_reverse(inew_taps);
+ unsigned len = new_taps.size ();
+
+ // Make 4 copies of the coefficients, one for each data alignment
+ // Note use of special 16-byte-aligned version of calloc()
+
+ for (unsigned i = 0; i < 4; i++){
+ free16Align (d_aligned_taps[i]); // free old value
+
+ // this works because the bit representation of a IEEE floating point
+ // +zero is all zeros. If you're using a different representation,
+ // you'll need to explictly set the result to the appropriate 0.0 value.
+
+ d_aligned_taps[i] = (float *) calloc16Align (1 + (len + i - 1) / 2,
+ 2 * 4 * sizeof (float));
+ if (d_aligned_taps[i] == 0){
+ // throw something...
+ cerr << "@@@ gr_fir_ccc_simd d_aligned_taps[" << i << "] == 0\n";
+ }
+
+ for (unsigned j = 0; j < len; j++) {
+ d_aligned_taps[i][2*(j+i)] = new_taps[j].real();
+ d_aligned_taps[i][2*(j+i)+1] = new_taps[j].imag();
+ }
+ }
+}
+
+gr_complex
+gr_fir_ccc_simd::filter (const gr_complex input[])
+{
+ if (ntaps () == 0)
+ return 0.0;
+
+
+ // Round input data address down to 16 byte boundary
+ // NB: depending on the alignment of input[], memory
+ // before input[] will be accessed. The contents don't matter since
+ // they'll be multiplied by zero coefficients. I can't conceive of any
+ // situation where this could cause a segfault since memory protection
+ // in the x86 machines is done on much larger boundaries.
+
+ const gr_complex *ar = (gr_complex *)((unsigned long) input & ~15);
+
+ // Choose one of 4 sets of pre-shifted coefficients. al is both the
+ // index into d_aligned_taps[] and the number of 0 words padded onto
+ // that coefficients array for alignment purposes.
+
+ unsigned al = input - ar;
+
+ // call assembler routine to do the work, passing number of 2x4-float blocks.
+
+ // assert (((unsigned long) ar & 15) == 0);
+ // assert (((unsigned long) d_aligned_taps[al] & 15) == 0);
+
+ // cerr << "ar: " << ar << " d_aligned_taps[ar]: " << d_aligned_taps[al]
+ // << " (ntaps() + al - 1)/2 + 1: " << (ntaps() + al -1) / 2 + 1 << endl;
+
+ float result[2];
+
+ d_ccomplex_dotprod ((float*)ar, d_aligned_taps[al], (ntaps() + al - 1) / 2 + 1, result);
+
+ // cerr << "result = " << result[0] << " " << result[1] << endl;
+
+ return gr_complex(result[0], result[1]);
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_ccc_simd.h b/gnuradio-core/src/lib/filter/gr_fir_ccc_simd.h
new file mode 100644
index 0000000000..8988887110
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_ccc_simd.h
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_FIR_CCC_SIMD_H
+#define INCLUDED_GR_FIR_CCC_SIMD_H
+
+#include <gr_fir_ccc_generic.h>
+
+/*!
+ * \brief common base class for SIMD versions of gr_fir_ccc
+ *
+ * This base class handles alignment issues common to SSE and 3DNOW
+ * subclasses.
+ */
+
+class gr_fir_ccc_simd : public gr_fir_ccc_generic
+{
+protected:
+ typedef void (*ccomplex_dotprod_t)(const float *input,
+ const float *taps,
+ unsigned n_2_ccomplex_blocks,
+ float *result);
+
+ /*!
+ * \p aligned_taps holds 4 copies of the coefficients preshifted
+ * by 0, 1, 2, or 3 floats to meet all possible input data alignments.
+ * This allows us to always fetch data and taps that are 128-bit aligned.
+ */
+ float *d_aligned_taps[4];
+
+ ccomplex_dotprod_t d_ccomplex_dotprod; // fast dot product primitive
+
+public:
+
+ // CREATORS
+ gr_fir_ccc_simd ();
+ gr_fir_ccc_simd (const std::vector<gr_complex> &taps);
+ ~gr_fir_ccc_simd ();
+
+ // MANIPULATORS
+ virtual void set_taps (const std::vector<gr_complex> &taps);
+ virtual gr_complex filter (const gr_complex input[]);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_ccc_x86.cc b/gnuradio-core/src/lib/filter/gr_fir_ccc_x86.cc
new file mode 100644
index 0000000000..8b96c23d6e
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_ccc_x86.h>
+#include <ccomplex_dotprod_x86.h>
+
+/*
+ * --- 3DNow! version ---
+ */
+
+gr_fir_ccc_3dnow::gr_fir_ccc_3dnow ()
+ : gr_fir_ccc_simd ()
+{
+ d_ccomplex_dotprod = ccomplex_dotprod_3dnow;
+}
+
+gr_fir_ccc_3dnow::gr_fir_ccc_3dnow (const std::vector<gr_complex> &new_taps)
+ : gr_fir_ccc_simd (new_taps)
+{
+ d_ccomplex_dotprod = ccomplex_dotprod_3dnow;
+}
+
+
+/*
+ * --- 3DNow!Ext version ---
+ */
+
+gr_fir_ccc_3dnowext::gr_fir_ccc_3dnowext ()
+ : gr_fir_ccc_simd ()
+{
+ d_ccomplex_dotprod = ccomplex_dotprod_3dnowext;
+}
+
+gr_fir_ccc_3dnowext::gr_fir_ccc_3dnowext (const std::vector<gr_complex> &new_taps)
+ : gr_fir_ccc_simd (new_taps)
+{
+ d_ccomplex_dotprod = ccomplex_dotprod_3dnowext;
+}
+
+
+/*
+ * --- SSE version ---
+ */
+
+gr_fir_ccc_sse::gr_fir_ccc_sse ()
+ : gr_fir_ccc_simd ()
+{
+ d_ccomplex_dotprod = ccomplex_dotprod_sse;
+}
+
+gr_fir_ccc_sse::gr_fir_ccc_sse (const std::vector<gr_complex> &new_taps)
+ : gr_fir_ccc_simd (new_taps)
+{
+ d_ccomplex_dotprod = ccomplex_dotprod_sse;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_ccc_x86.h b/gnuradio-core/src/lib/filter/gr_fir_ccc_x86.h
new file mode 100644
index 0000000000..ee2fe9b1f8
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_ccc_x86.h
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_FIR_CCC_X86_H
+#define INCLUDED_GR_FIR_CCC_X86_H
+
+#include <gr_fir_ccc_simd.h>
+
+/*!
+ * \brief 3DNow! version of gr_fir_ccc
+ */
+class gr_fir_ccc_3dnow : public gr_fir_ccc_simd
+{
+public:
+ gr_fir_ccc_3dnow ();
+ gr_fir_ccc_3dnow (const std::vector<gr_complex> &taps);
+};
+
+class gr_fir_ccc_3dnowext : public gr_fir_ccc_simd
+{
+public:
+ gr_fir_ccc_3dnowext ();
+ gr_fir_ccc_3dnowext (const std::vector<gr_complex> &taps);
+};
+
+/*!
+ * \brief SSE version of gr_fir_ccc
+ */
+class gr_fir_ccc_sse : public gr_fir_ccc_simd
+{
+public:
+ gr_fir_ccc_sse ();
+ gr_fir_ccc_sse (const std::vector<gr_complex> &taps);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_ccf_simd.cc b/gnuradio-core/src/lib/filter/gr_fir_ccf_simd.cc
new file mode 100644
index 0000000000..d1992d7c99
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_ccf_simd.cc
@@ -0,0 +1,138 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_ccf_simd.h>
+
+#include <assert.h>
+#include <malloc16.h>
+#include <iostream>
+
+using std::cerr;
+using std::endl;
+
+gr_fir_ccf_simd::gr_fir_ccf_simd ()
+ : gr_fir_ccf_generic ()
+{
+ // cerr << "@@@ gr_fir_ccf_simd\n";
+
+ d_fcomplex_dotprod = 0;
+
+ d_aligned_taps[0] = 0;
+ d_aligned_taps[1] = 0;
+ d_aligned_taps[2] = 0;
+ d_aligned_taps[3] = 0;
+}
+
+gr_fir_ccf_simd::gr_fir_ccf_simd (const std::vector<float> &new_taps)
+ : gr_fir_ccf_generic (new_taps)
+{
+ // cerr << "@@@ gr_fir_ccf_simd\n";
+
+ d_fcomplex_dotprod = 0;
+
+ d_aligned_taps[0] = 0;
+ d_aligned_taps[1] = 0;
+ d_aligned_taps[2] = 0;
+ d_aligned_taps[3] = 0;
+ set_taps (new_taps);
+}
+
+gr_fir_ccf_simd::~gr_fir_ccf_simd ()
+{
+ free16Align (d_aligned_taps[0]);
+ free16Align (d_aligned_taps[1]);
+ free16Align (d_aligned_taps[2]);
+ free16Align (d_aligned_taps[3]);
+}
+
+void
+gr_fir_ccf_simd::set_taps (const std::vector<float> &inew_taps)
+{
+ gr_fir_ccf::set_taps (inew_taps); // call superclass
+ const std::vector<float> new_taps = gr_reverse(inew_taps);
+
+ unsigned len = new_taps.size ();
+
+ // Make 4 copies of the coefficients, one for each data alignment
+ // Note use of special 16-byte-aligned version of calloc()
+
+ for (unsigned i = 0; i < 4; i++){
+ free16Align (d_aligned_taps[i]); // free old value
+
+ // this works because the bit representation of a IEEE floating point
+ // +zero is all zeros. If you're using a different representation,
+ // you'll need to explictly set the result to the appropriate 0.0 value.
+
+ d_aligned_taps[i] = (float *) calloc16Align (1 + (len + i - 1) / 4,
+ 4 * sizeof (float));
+ if (d_aligned_taps[i] == 0){
+ // throw something...
+ cerr << "@@@ gr_fir_ccf_simd d_aligned_taps[" << i << "] == 0\n";
+ }
+
+ for (unsigned j = 0; j < len; j++)
+ d_aligned_taps[i][j+i] = new_taps[j];
+ }
+}
+
+gr_complex
+gr_fir_ccf_simd::filter (const gr_complex input[])
+{
+ if (ntaps () == 0)
+ return 0.0;
+
+
+ // Round input data address down to 16 byte boundary
+ // NB: depending on the alignment of input[], memory
+ // before input[] will be accessed. The contents don't matter since
+ // they'll be multiplied by zero coefficients. I can't conceive of any
+ // situation where this could cause a segfault since memory protection
+ // in the x86 machines is done on much larger boundaries.
+
+ const gr_complex *ar = (gr_complex *)((unsigned long) input & ~15);
+
+ // Choose one of 4 sets of pre-shifted coefficients. al is both the
+ // index into d_aligned_taps[] and the number of 0 words padded onto
+ // that coefficients array for alignment purposes.
+
+ unsigned al = input - ar;
+
+ // call assembler routine to do the work, passing number of 2x4-float blocks.
+
+ // assert (((unsigned long) ar & 15) == 0);
+ // assert (((unsigned long) d_aligned_taps[al] & 15) == 0);
+
+ // cerr << "ar: " << ar << " d_aligned_taps[ar]: " << d_aligned_taps[al]
+ // << " (ntaps() + al - 1)/2 + 1: " << (ntaps() + al -1) / 2 + 1 << endl;
+
+ float result[2];
+
+ // the trick here is to invert input and taps, and reuse FCC speedup
+ d_fcomplex_dotprod (d_aligned_taps[al], (float*)ar, (ntaps() + al - 1) / 2 + 1, result);
+
+ // cerr << "result = " << result[0] << " " << result[1] << endl;
+
+ return gr_complex(result[0], result[1]);
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_ccf_simd.h b/gnuradio-core/src/lib/filter/gr_fir_ccf_simd.h
new file mode 100644
index 0000000000..60898b43d7
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_ccf_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_FIR_CCF_SIMD_H
+#define INCLUDED_GR_FIR_CCF_SIMD_H
+
+#include <gr_fir_ccf_generic.h>
+
+
+/*!
+ * \brief common base class for SIMD versions of gr_fir_ccf
+ *
+ * This base class handles alignment issues common to SSE and 3DNOW
+ * subclasses.
+ */
+
+class gr_fir_ccf_simd : public gr_fir_ccf_generic
+{
+protected:
+ typedef void (*fcomplex_dotprod_t)(const float *taps,
+ const float *input,
+ unsigned n_2_complex_blocks,
+ float *result);
+
+ /*!
+ * \p aligned_taps holds 4 copies of the coefficients preshifted
+ * by 0, 1, 2, or 3 float pairs to meet all possible input data alignments.
+ * This allows us to always fetch data and taps that are 128-bit aligned.
+ */
+ float *d_aligned_taps[4];
+
+ fcomplex_dotprod_t d_fcomplex_dotprod; // fast dot product primitive
+
+public:
+
+ // CREATORS
+ gr_fir_ccf_simd ();
+ gr_fir_ccf_simd (const std::vector<float> &taps);
+ ~gr_fir_ccf_simd ();
+
+ // MANIPULATORS
+ virtual void set_taps (const std::vector<float> &taps);
+ virtual gr_complex filter (const gr_complex input[]);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_ccf_x86.cc b/gnuradio-core/src/lib/filter/gr_fir_ccf_x86.cc
new file mode 100644
index 0000000000..9f288fc221
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_ccf_x86.h>
+#include <fcomplex_dotprod_x86.h>
+
+/*
+ * --- 3DNow! version ---
+ */
+
+gr_fir_ccf_3dnow::gr_fir_ccf_3dnow ()
+ : gr_fir_ccf_simd ()
+{
+ d_fcomplex_dotprod = fcomplex_dotprod_3dnow;
+}
+
+gr_fir_ccf_3dnow::gr_fir_ccf_3dnow (const std::vector<float> &new_taps)
+ : gr_fir_ccf_simd (new_taps)
+{
+ d_fcomplex_dotprod = fcomplex_dotprod_3dnow;
+}
+
+
+/*
+ * --- SSE version ---
+ */
+
+gr_fir_ccf_sse::gr_fir_ccf_sse ()
+ : gr_fir_ccf_simd ()
+{
+ d_fcomplex_dotprod = fcomplex_dotprod_sse;
+}
+
+gr_fir_ccf_sse::gr_fir_ccf_sse (const std::vector<float> &new_taps)
+ : gr_fir_ccf_simd (new_taps)
+{
+ d_fcomplex_dotprod = fcomplex_dotprod_sse;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_ccf_x86.h b/gnuradio-core/src/lib/filter/gr_fir_ccf_x86.h
new file mode 100644
index 0000000000..5c51a5f931
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_ccf_x86.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_FIR_CCF_X86_H
+#define INCLUDED_GR_FIR_CCF_X86_H
+
+#include <gr_fir_ccf_simd.h>
+
+/*!
+ * \brief 3DNow! version of gr_fir_ccf
+ */
+class gr_fir_ccf_3dnow : public gr_fir_ccf_simd
+{
+public:
+ gr_fir_ccf_3dnow ();
+ gr_fir_ccf_3dnow (const std::vector<float> &taps);
+};
+
+/*!
+ * \brief SSE version of gr_fir_ccf
+ */
+class gr_fir_ccf_sse : public gr_fir_ccf_simd
+{
+public:
+ gr_fir_ccf_sse ();
+ gr_fir_ccf_sse (const std::vector<float> &taps);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fcc_simd.cc b/gnuradio-core/src/lib/filter/gr_fir_fcc_simd.cc
new file mode 100644
index 0000000000..c17d29f7da
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_fcc_simd.h>
+
+#include <assert.h>
+#include <malloc16.h>
+#include <iostream>
+
+using std::cerr;
+using std::endl;
+
+gr_fir_fcc_simd::gr_fir_fcc_simd ()
+ : gr_fir_fcc_generic ()
+{
+ // cerr << "@@@ gr_fir_fcc_simd\n";
+
+ d_fcomplex_dotprod = 0;
+
+ d_aligned_taps[0] = 0;
+ d_aligned_taps[1] = 0;
+ d_aligned_taps[2] = 0;
+ d_aligned_taps[3] = 0;
+}
+
+gr_fir_fcc_simd::gr_fir_fcc_simd (const std::vector<gr_complex> &new_taps)
+ : gr_fir_fcc_generic (new_taps)
+{
+ // cerr << "@@@ gr_fir_fcc_simd\n";
+
+ d_fcomplex_dotprod = 0;
+
+ d_aligned_taps[0] = 0;
+ d_aligned_taps[1] = 0;
+ d_aligned_taps[2] = 0;
+ d_aligned_taps[3] = 0;
+ set_taps (new_taps);
+}
+
+gr_fir_fcc_simd::~gr_fir_fcc_simd ()
+{
+ free16Align (d_aligned_taps[0]);
+ free16Align (d_aligned_taps[1]);
+ free16Align (d_aligned_taps[2]);
+ free16Align (d_aligned_taps[3]);
+}
+
+void
+gr_fir_fcc_simd::set_taps (const std::vector<gr_complex> &inew_taps)
+{
+ gr_fir_fcc::set_taps (inew_taps); // call superclass
+ const std::vector<gr_complex> new_taps = gr_reverse(inew_taps);
+
+ unsigned len = new_taps.size ();
+
+ // Make 4 copies of the coefficients, one for each data alignment
+ // Note use of special 16-byte-aligned version of calloc()
+
+ for (unsigned i = 0; i < 4; i++){
+ free16Align (d_aligned_taps[i]); // free old value
+
+ // this works because the bit representation of a IEEE floating point
+ // +zero is all zeros. If you're using a different representation,
+ // you'll need to explictly set the result to the appropriate 0.0 value.
+
+ d_aligned_taps[i] = (float *) calloc16Align (1 + (len + i - 1) / 2,
+ 2 * 4 * sizeof (float));
+ if (d_aligned_taps[i] == 0){
+ // throw something...
+ cerr << "@@@ gr_fir_fcc_simd d_aligned_taps[" << i << "] == 0\n";
+ }
+
+ for (unsigned j = 0; j < len; j++) {
+ d_aligned_taps[i][2*(j+i)] = new_taps[j].real();
+ d_aligned_taps[i][2*(j+i)+1] = new_taps[j].imag();
+ }
+ }
+}
+
+gr_complex
+gr_fir_fcc_simd::filter (const float input[])
+{
+ if (ntaps () == 0)
+ return 0.0;
+
+
+ // Round input data address down to 16 byte boundary
+ // NB: depending on the alignment of input[], memory
+ // before input[] will be accessed. The contents don't matter since
+ // they'll be multiplied by zero coefficients. I can't conceive of any
+ // situation where this could cause a segfault since memory protection
+ // in the x86 machines is done on much larger boundaries.
+
+ const float *ar = (float *)((unsigned long) input & ~15);
+
+ // Choose one of 4 sets of pre-shifted coefficients. al is both the
+ // index into d_aligned_taps[] and the number of 0 words padded onto
+ // that coefficients array for alignment purposes.
+
+ unsigned al = input - ar;
+
+ // call assembler routine to do the work, passing number of 2x4-float blocks.
+
+ // assert (((unsigned long) ar & 15) == 0);
+ // assert (((unsigned long) d_aligned_taps[al] & 15) == 0);
+
+ // cerr << "ar: " << ar << " d_aligned_taps[ar]: " << d_aligned_taps[al]
+ // << " (ntaps() + al - 1)/2 + 1: " << (ntaps() + al -1) / 2 + 1 << endl;
+
+ float result[2];
+
+ d_fcomplex_dotprod (ar, d_aligned_taps[al], (ntaps() + al - 1) / 2 + 1, result);
+
+ // cerr << "result = " << result[0] << " " << result[1] << endl;
+
+ return gr_complex(result[0], result[1]);
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fcc_simd.h b/gnuradio-core/src/lib/filter/gr_fir_fcc_simd.h
new file mode 100644
index 0000000000..5624820902
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_fcc_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_FIR_FCC_SIMD_H
+#define INCLUDED_GR_FIR_FCC_SIMD_H
+
+#include <gr_fir_fcc_generic.h>
+
+
+/*!
+ * \brief common base class for SIMD versions of gr_fir_fcc
+ *
+ * This base class handles alignment issues common to SSE and 3DNOW
+ * subclasses.
+ */
+
+class gr_fir_fcc_simd : public gr_fir_fcc_generic
+{
+protected:
+ typedef void (*fcomplex_dotprod_t)(const float *input,
+ const float *taps,
+ unsigned n_2_complex_blocks,
+ float *result);
+
+ /*!
+ * \p aligned_taps holds 4 copies of the coefficients preshifted
+ * by 0, 1, 2, or 3 float pairs to meet all possible input data alignments.
+ * This allows us to always fetch data and taps that are 128-bit aligned.
+ */
+ float *d_aligned_taps[4];
+
+ fcomplex_dotprod_t d_fcomplex_dotprod; // fast dot product primitive
+
+public:
+
+ // CREATORS
+ gr_fir_fcc_simd ();
+ gr_fir_fcc_simd (const std::vector<gr_complex> &taps);
+ ~gr_fir_fcc_simd ();
+
+ // MANIPULATORS
+ virtual void set_taps (const std::vector<gr_complex> &taps);
+ virtual gr_complex filter (const float input[]);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fcc_x86.cc b/gnuradio-core/src/lib/filter/gr_fir_fcc_x86.cc
new file mode 100644
index 0000000000..e80dfe1f4f
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_fcc_x86.h>
+#include <fcomplex_dotprod_x86.h>
+
+/*
+ * --- 3DNow! version ---
+ */
+
+gr_fir_fcc_3dnow::gr_fir_fcc_3dnow ()
+ : gr_fir_fcc_simd ()
+{
+ d_fcomplex_dotprod = fcomplex_dotprod_3dnow;
+}
+
+gr_fir_fcc_3dnow::gr_fir_fcc_3dnow (const std::vector<gr_complex> &new_taps)
+ : gr_fir_fcc_simd (new_taps)
+{
+ d_fcomplex_dotprod = fcomplex_dotprod_3dnow;
+}
+
+
+/*
+ * --- SSE version ---
+ */
+
+gr_fir_fcc_sse::gr_fir_fcc_sse ()
+ : gr_fir_fcc_simd ()
+{
+ d_fcomplex_dotprod = fcomplex_dotprod_sse;
+}
+
+gr_fir_fcc_sse::gr_fir_fcc_sse (const std::vector<gr_complex> &new_taps)
+ : gr_fir_fcc_simd (new_taps)
+{
+ d_fcomplex_dotprod = fcomplex_dotprod_sse;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fcc_x86.h b/gnuradio-core/src/lib/filter/gr_fir_fcc_x86.h
new file mode 100644
index 0000000000..500f4fb5f0
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_fcc_x86.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_FIR_FCC_X86_H
+#define INCLUDED_GR_FIR_FCC_X86_H
+
+#include <gr_fir_fcc_simd.h>
+
+/*!
+ * \brief 3DNow! version of gr_fir_fcc
+ */
+class gr_fir_fcc_3dnow : public gr_fir_fcc_simd
+{
+public:
+ gr_fir_fcc_3dnow ();
+ gr_fir_fcc_3dnow (const std::vector<gr_complex> &taps);
+};
+
+/*!
+ * \brief SSE version of gr_fir_fcc
+ */
+class gr_fir_fcc_sse : public gr_fir_fcc_simd
+{
+public:
+ gr_fir_fcc_sse ();
+ gr_fir_fcc_sse (const std::vector<gr_complex> &taps);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fff_simd.cc b/gnuradio-core/src/lib/filter/gr_fir_fff_simd.cc
new file mode 100644
index 0000000000..92c4256e07
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_fff_simd.h>
+
+#include <assert.h>
+#include <malloc16.h>
+#include <iostream>
+
+using std::cerr;
+
+gr_fir_fff_simd::gr_fir_fff_simd ()
+ : gr_fir_fff_generic ()
+{
+ // cerr << "@@@ gr_fir_fff_simd\n";
+
+ d_float_dotprod = 0;
+
+ d_aligned_taps[0] = 0;
+ d_aligned_taps[1] = 0;
+ d_aligned_taps[2] = 0;
+ d_aligned_taps[3] = 0;
+}
+
+gr_fir_fff_simd::gr_fir_fff_simd (const std::vector<float> &new_taps)
+ : gr_fir_fff_generic (new_taps)
+{
+ // cerr << "@@@ gr_fir_fff_simd\n";
+
+ d_float_dotprod = 0;
+
+ d_aligned_taps[0] = 0;
+ d_aligned_taps[1] = 0;
+ d_aligned_taps[2] = 0;
+ d_aligned_taps[3] = 0;
+ set_taps (new_taps);
+}
+
+gr_fir_fff_simd::~gr_fir_fff_simd ()
+{
+ free16Align (d_aligned_taps[0]);
+ free16Align (d_aligned_taps[1]);
+ free16Align (d_aligned_taps[2]);
+ free16Align (d_aligned_taps[3]);
+}
+
+void
+gr_fir_fff_simd::set_taps (const std::vector<float> &inew_taps)
+{
+ gr_fir_fff::set_taps (inew_taps); // call superclass
+ const std::vector<float> new_taps = gr_reverse(inew_taps);
+
+ unsigned len = new_taps.size ();
+
+ // Make 4 copies of the coefficients, one for each data alignment
+ // Note use of special 16-byte-aligned version of calloc()
+
+ for (unsigned i = 0; i < 4; i++){
+ free16Align (d_aligned_taps[i]); // free old value
+
+ // this works because the bit representation of a IEEE floating point
+ // +zero is all zeros. If you're using a different representation,
+ // you'll need to explictly set the result to the appropriate 0.0 value.
+
+ d_aligned_taps[i] = (float *) calloc16Align (1 + (len + i - 1) / 4,
+ 4 * sizeof (float));
+ if (d_aligned_taps[i] == 0){
+ // throw something...
+ cerr << "@@@ gr_fir_fff_simd d_aligned_taps[" << i << "] == 0\n";
+ }
+
+ for (unsigned j = 0; j < len; j++)
+ d_aligned_taps[i][j+i] = new_taps[j];
+ }
+}
+
+float
+gr_fir_fff_simd::filter (const float input[])
+{
+ if (ntaps () == 0)
+ return 0.0;
+
+
+ // Round input data address down to 16 byte boundary
+ // NB: depending on the alignment of input[], memory
+ // before input[] will be accessed. The contents don't matter since
+ // they'll be multiplied by zero coefficients. I can't conceive of any
+ // situation where this could cause a segfault since memory protection
+ // in the x86 machines is done on much larger boundaries.
+
+ const float *ar = (float *)((unsigned long) input & ~15);
+
+ // Choose one of 4 sets of pre-shifted coefficients. al is both the
+ // index into d_aligned_taps[] and the number of 0 words padded onto
+ // that coefficients array for alignment purposes.
+
+ unsigned al = input - ar;
+
+ // call assembler routine to do the work, passing number of 4-float blocks.
+
+ // assert (((unsigned long) ar & 15) == 0);
+ // assert (((unsigned long) d_aligned_taps[al] & 15) == 0);
+
+ // cerr << "ar: " << ar << " d_aligned_taps[ar]: " << d_aligned_taps[al]
+ // << " (ntaps() + al - 1)/4 + 1: " << (ntaps() + al -1) / 4 + 1 << endl;
+
+ float r = d_float_dotprod (ar, d_aligned_taps[al], (ntaps() + al - 1) / 4 + 1);
+
+ // cerr << "result = " << r << endl;
+
+ return r;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fff_simd.h b/gnuradio-core/src/lib/filter/gr_fir_fff_simd.h
new file mode 100644
index 0000000000..375b1191b3
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_fff_simd.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_FIR_FFF_SIMD_H
+#define INCLUDED_GR_FIR_FFF_SIMD_H
+
+#include <gr_fir_fff_generic.h>
+
+/*!
+ * \brief common base class for SIMD versions of gr_fir_fff
+ *
+ * This base class handles alignment issues common to SSE and 3DNOW
+ * subclasses.
+ */
+
+class gr_fir_fff_simd : public gr_fir_fff_generic
+{
+protected:
+ typedef float (*float_dotprod_t)(const float *input,
+ const float *taps,
+ unsigned n_4_float_blocks);
+
+ /*!
+ * \p aligned_taps holds 4 copies of the coefficients preshifted
+ * by 0, 1, 2, or 3 floats to meet all possible input data alignments.
+ * This allows us to always fetch data and taps that are 128-bit aligned.
+ */
+ float *d_aligned_taps[4];
+
+ float_dotprod_t d_float_dotprod; // fast dot product primitive
+
+public:
+
+ // CREATORS
+ gr_fir_fff_simd ();
+ gr_fir_fff_simd (const std::vector<float> &taps);
+ ~gr_fir_fff_simd ();
+
+ // MANIPULATORS
+ virtual void set_taps (const std::vector<float> &taps);
+ virtual float filter (const float input[]);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fff_x86.cc b/gnuradio-core/src/lib/filter/gr_fir_fff_x86.cc
new file mode 100644
index 0000000000..494a0f7e7c
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_fff_x86.h>
+#include <float_dotprod_x86.h>
+
+/*
+ * --- 3DNow! version ---
+ */
+
+gr_fir_fff_3dnow::gr_fir_fff_3dnow ()
+ : gr_fir_fff_simd ()
+{
+ d_float_dotprod = float_dotprod_3dnow;
+}
+
+gr_fir_fff_3dnow::gr_fir_fff_3dnow (const std::vector<float> &new_taps)
+ : gr_fir_fff_simd (new_taps)
+{
+ d_float_dotprod = float_dotprod_3dnow;
+}
+
+
+/*
+ * --- SSE version ---
+ */
+
+gr_fir_fff_sse::gr_fir_fff_sse ()
+ : gr_fir_fff_simd ()
+{
+ d_float_dotprod = float_dotprod_sse;
+}
+
+gr_fir_fff_sse::gr_fir_fff_sse (const std::vector<float> &new_taps)
+ : gr_fir_fff_simd (new_taps)
+{
+ d_float_dotprod = float_dotprod_sse;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fff_x86.h b/gnuradio-core/src/lib/filter/gr_fir_fff_x86.h
new file mode 100644
index 0000000000..407ae3ffcb
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_fff_x86.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_FIR_FFF_X86_H
+#define INCLUDED_GR_FIR_FFF_X86_H
+
+#include <gr_fir_fff_simd.h>
+
+/*!
+ * \brief 3DNow! version of gr_fir_fff
+ */
+class gr_fir_fff_3dnow : public gr_fir_fff_simd
+{
+public:
+ gr_fir_fff_3dnow ();
+ gr_fir_fff_3dnow (const std::vector<float> &taps);
+};
+
+/*!
+ * \brief SSE version of gr_fir_fff
+ */
+class gr_fir_fff_sse : public gr_fir_fff_simd
+{
+public:
+ gr_fir_fff_sse ();
+ gr_fir_fff_sse (const std::vector<float> &taps);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.cc.t b/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.cc.t
new file mode 100644
index 0000000000..91b3111e99
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.cc.t
@@ -0,0 +1,88 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * WARNING: This file is automatically generated by generate_gr_fir_filter_XXX.py
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <@FIR_TYPE@.h>
+#include <gr_fir_util.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps)
+{
+ return @SPTR_NAME@ (new @NAME@ (decimation, taps));
+}
+
+
+@NAME@::@NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps)
+ : gr_sync_decimator ("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@)),
+ decimation),
+ d_updated (false)
+{
+ d_fir = gr_fir_util::create_@FIR_TYPE@ (taps);
+ set_history (d_fir->ntaps ());
+}
+
+@NAME@::~@NAME@ ()
+{
+ delete d_fir;
+}
+
+void
+@NAME@::set_taps (const std::vector<@TAP_TYPE@> &taps)
+{
+ d_new_taps = taps;
+ d_updated = true;
+}
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ @I_TYPE@ *in = (@I_TYPE@ *) input_items[0];
+ @O_TYPE@ *out = (@O_TYPE@ *) output_items[0];
+
+ if (d_updated) {
+ d_fir->set_taps (d_new_taps);
+ set_history (d_fir->ntaps ());
+ d_updated = false;
+ return 0; // history requirements may have changed.
+ }
+
+ if (decimation() == 1)
+ d_fir->filterN (out, in, noutput_items);
+
+ else
+ d_fir->filterNdec (out, in, noutput_items, decimation());
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.h.t b/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.h.t
new file mode 100644
index 0000000000..b6e5d1aa60
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.h.t
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * WARNING: This file is automatically generated by generate_gr_fir_filter_XXX.py
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_decimator.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+@SPTR_NAME@ gr_make_@BASE_NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps);
+
+class @FIR_TYPE@;
+
+/*!
+ * \brief FIR filter with @I_TYPE@ input, @O_TYPE@ output and @TAP_TYPE@ taps
+ * \ingroup filter
+ */
+class @NAME@ : public gr_sync_decimator
+{
+ private:
+ friend @SPTR_NAME@ gr_make_@BASE_NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps);
+
+ @FIR_TYPE@ *d_fir;
+ std::vector<@TAP_TYPE@> d_new_taps;
+ bool d_updated;
+
+ /*!
+ * Construct a FIR filter with the given taps
+ */
+ @NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps);
+
+ public:
+ ~@NAME@ ();
+
+ void set_taps (const std::vector<@TAP_TYPE@> &taps);
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.i.t b/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.i.t
new file mode 100644
index 0000000000..13c919d1ab
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * WARNING: This file is automatically generated by generate_GrFIRfilterXXX.py
+ * Any changes made to this file will be overwritten.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps);
+
+class @NAME@ : public gr_sync_decimator
+{
+ private:
+ @NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps);
+
+ public:
+ ~@NAME@ ();
+
+ void set_taps (const std::vector<@TAP_TYPE@> &taps);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fsf_simd.cc b/gnuradio-core/src/lib/filter/gr_fir_fsf_simd.cc
new file mode 100644
index 0000000000..00b4e60997
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_fsf_simd.h>
+
+#include <assert.h>
+#include <malloc16.h>
+#include <iostream>
+
+using std::cerr;
+
+gr_fir_fsf_simd::gr_fir_fsf_simd ()
+ : gr_fir_fsf_generic ()
+{
+ // cerr << "@@@ gr_fir_fsf_simd\n";
+
+ d_float_dotprod = 0;
+
+ d_aligned_taps[0] = 0;
+ d_aligned_taps[1] = 0;
+ d_aligned_taps[2] = 0;
+ d_aligned_taps[3] = 0;
+}
+
+gr_fir_fsf_simd::gr_fir_fsf_simd (const std::vector<float> &new_taps)
+ : gr_fir_fsf_generic (new_taps)
+{
+ // cerr << "@@@ gr_fir_fsf_simd\n";
+
+ d_float_dotprod = 0;
+
+ d_aligned_taps[0] = 0;
+ d_aligned_taps[1] = 0;
+ d_aligned_taps[2] = 0;
+ d_aligned_taps[3] = 0;
+ set_taps (new_taps);
+}
+
+gr_fir_fsf_simd::~gr_fir_fsf_simd ()
+{
+ free16Align (d_aligned_taps[0]);
+ free16Align (d_aligned_taps[1]);
+ free16Align (d_aligned_taps[2]);
+ free16Align (d_aligned_taps[3]);
+}
+
+void
+gr_fir_fsf_simd::set_taps (const std::vector<float> &inew_taps)
+{
+ gr_fir_fsf::set_taps (inew_taps); // call superclass
+ const std::vector<float> new_taps = gr_reverse(inew_taps);
+ unsigned len = new_taps.size ();
+
+ // Make 4 copies of the coefficients, one for each data alignment
+ // Note use of special 16-byte-aligned version of calloc()
+
+ for (unsigned i = 0; i < 4; i++){
+ free16Align (d_aligned_taps[i]); // free old value
+
+ // this works because the bit representation of a IEEE floating point
+ // +zero is all zeros. If you're using a different representation,
+ // you'll need to explictly set the result to the appropriate 0.0 value.
+
+ d_aligned_taps[i] = (float *) calloc16Align (1 + (len + i - 1) / 4,
+ 4 * sizeof (float));
+ if (d_aligned_taps[i] == 0){
+ // throw something...
+ cerr << "@@@ gr_fir_fsf_simd d_aligned_taps[" << i << "] == 0\n";
+ }
+
+ for (unsigned j = 0; j < len; j++)
+ d_aligned_taps[i][j+i] = new_taps[j];
+ }
+}
+
+short
+gr_fir_fsf_simd::filter (const float input[])
+{
+ if (ntaps () == 0)
+ return 0;
+
+
+ // Round input data address down to 16 byte boundary
+ // NB: depending on the alignment of input[], memory
+ // before input[] will be accessed. The contents don't matter since
+ // they'll be multiplied by zero coefficients. I can't conceive of any
+ // situation where this could cause a segfault since memory protection
+ // in the x86 machines is done on much larger boundaries.
+
+ const float *ar = (float *)((unsigned long) input & ~15);
+
+ // Choose one of 4 sets of pre-shifted coefficients. al is both the
+ // index into d_aligned_taps[] and the number of 0 words padded onto
+ // that coefficients array for alignment purposes.
+
+ unsigned al = input - ar;
+
+ // call assembler routine to do the work, passing number of 4-float blocks.
+
+ // assert (((unsigned long) ar & 15) == 0);
+ // assert (((unsigned long) d_aligned_taps[al] & 15) == 0);
+
+ // cerr << "ar: " << ar << " d_aligned_taps[ar]: " << d_aligned_taps[al]
+ // << " (ntaps() + al - 1)/4 + 1: " << (ntaps() + al -1) / 4 + 1 << endl;
+
+ float r = d_float_dotprod (ar, d_aligned_taps[al], (ntaps() + al - 1) / 4 + 1);
+
+ // cerr << "result = " << r << endl;
+
+ return (short) r; // FIXME? may want to saturate here
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fsf_simd.h b/gnuradio-core/src/lib/filter/gr_fir_fsf_simd.h
new file mode 100644
index 0000000000..77e093ca84
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_fsf_simd.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _GR_FIR_FSF_SIMD_H_
+#define _GR_FIR_FSF_SIMD_H_
+
+#include <gr_fir_fsf_generic.h>
+
+/*!
+ * \brief common base class for SIMD versions of gr_fir_fsf
+ *
+ * This base class handles alignment issues common to SSE and 3DNOW
+ * subclasses.
+ */
+
+class gr_fir_fsf_simd : public gr_fir_fsf_generic
+{
+protected:
+ typedef float (*float_dotprod_t)(const float *input,
+ const float *taps,
+ unsigned n_4_float_blocks);
+
+ /*!
+ * \p aligned_taps holds 4 copies of the coefficients preshifted
+ * by 0, 1, 2, or 3 floats to meet all possible input data alignments.
+ * This allows us to always fetch data and taps that are 128-bit aligned.
+ */
+ float *d_aligned_taps[4];
+
+ float_dotprod_t d_float_dotprod; // fast dot product primitive
+
+public:
+
+ // CREATORS
+ gr_fir_fsf_simd ();
+ gr_fir_fsf_simd (const std::vector<float> &taps);
+ ~gr_fir_fsf_simd ();
+
+ // MANIPULATORS
+ virtual void set_taps (const std::vector<float> &taps);
+ virtual short filter (const float input[]);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fsf_x86.cc b/gnuradio-core/src/lib/filter/gr_fir_fsf_x86.cc
new file mode 100644
index 0000000000..c407789db7
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_fsf_x86.h>
+#include <float_dotprod_x86.h>
+
+/*
+ * --- 3DNow! version ---
+ */
+
+gr_fir_fsf_3dnow::gr_fir_fsf_3dnow ()
+ : gr_fir_fsf_simd ()
+{
+ d_float_dotprod = float_dotprod_3dnow;
+}
+
+gr_fir_fsf_3dnow::gr_fir_fsf_3dnow (const std::vector<float> &new_taps)
+ : gr_fir_fsf_simd (new_taps)
+{
+ d_float_dotprod = float_dotprod_3dnow;
+}
+
+
+/*
+ * --- SSE version ---
+ */
+
+gr_fir_fsf_sse::gr_fir_fsf_sse ()
+ : gr_fir_fsf_simd ()
+{
+ d_float_dotprod = float_dotprod_sse;
+}
+
+gr_fir_fsf_sse::gr_fir_fsf_sse (const std::vector<float> &new_taps)
+ : gr_fir_fsf_simd (new_taps)
+{
+ d_float_dotprod = float_dotprod_sse;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fsf_x86.h b/gnuradio-core/src/lib/filter/gr_fir_fsf_x86.h
new file mode 100644
index 0000000000..e8ae763f6c
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_fsf_x86.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_FIR_FSF_X86_H
+#define INCLUDED_GR_FIR_FSF_X86_H
+
+#include <gr_fir_fsf_simd.h>
+
+/*!
+ * \brief 3DNow! version of gr_fir_fsf
+ */
+class gr_fir_fsf_3dnow : public gr_fir_fsf_simd
+{
+public:
+ gr_fir_fsf_3dnow ();
+ gr_fir_fsf_3dnow (const std::vector<float> &taps);
+};
+
+/*!
+ * \brief SSE version of gr_fir_fsf
+ */
+class gr_fir_fsf_sse : public gr_fir_fsf_simd
+{
+public:
+ gr_fir_fsf_sse ();
+ gr_fir_fsf_sse (const std::vector<float> &taps);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_scc_simd.cc b/gnuradio-core/src/lib/filter/gr_fir_scc_simd.cc
new file mode 100644
index 0000000000..b6f91a7479
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_scc_simd.h>
+
+#include <assert.h>
+#include <malloc16.h>
+#include <iostream>
+
+using std::cerr;
+using std::endl;
+
+gr_fir_scc_simd::gr_fir_scc_simd ()
+ : gr_fir_scc_generic ()
+{
+ // cerr << "@@@ gr_fir_scc_simd\n";
+
+ d_complex_dotprod = 0;
+
+ d_aligned_taps[0] = 0;
+ d_aligned_taps[1] = 0;
+ d_aligned_taps[2] = 0;
+ d_aligned_taps[3] = 0;
+}
+
+gr_fir_scc_simd::gr_fir_scc_simd (const std::vector<gr_complex> &new_taps)
+ : gr_fir_scc_generic (new_taps)
+{
+ // cerr << "@@@ gr_fir_scc_simd\n";
+
+ d_complex_dotprod = 0;
+
+ d_aligned_taps[0] = 0;
+ d_aligned_taps[1] = 0;
+ d_aligned_taps[2] = 0;
+ d_aligned_taps[3] = 0;
+ set_taps (new_taps);
+}
+
+gr_fir_scc_simd::~gr_fir_scc_simd ()
+{
+ free16Align (d_aligned_taps[0]);
+ free16Align (d_aligned_taps[1]);
+ free16Align (d_aligned_taps[2]);
+ free16Align (d_aligned_taps[3]);
+}
+
+void
+gr_fir_scc_simd::set_taps (const std::vector<gr_complex> &inew_taps)
+{
+ gr_fir_scc::set_taps (inew_taps); // call superclass
+
+ const std::vector<gr_complex> new_taps = gr_reverse(inew_taps);
+
+ unsigned len = new_taps.size ();
+
+ // Make 4 copies of the coefficients, one for each data alignment
+ // Note use of special 16-byte-aligned version of calloc()
+
+ for (unsigned i = 0; i < 4; i++){
+ free16Align (d_aligned_taps[i]); // free old value
+
+ // this works because the bit representation of a IEEE floating point
+ // +zero is all zeros. If you're using a different representation,
+ // you'll need to explictly set the result to the appropriate 0.0 value.
+
+ d_aligned_taps[i] = (float *) calloc16Align (1 + (len + i - 1) / 2,
+ 2 * 4 * sizeof (float));
+ if (d_aligned_taps[i] == 0){
+ // throw something...
+ cerr << "@@@ gr_fir_scc_simd d_aligned_taps[" << i << "] == 0\n";
+ }
+
+ for (unsigned j = 0; j < len; j++) {
+ d_aligned_taps[i][2*(j+i)] = new_taps[j].real();
+ d_aligned_taps[i][2*(j+i)+1] = new_taps[j].imag();
+ }
+ }
+}
+
+gr_complex
+gr_fir_scc_simd::filter (const short input[])
+{
+ if (ntaps () == 0)
+ return 0.0;
+
+
+ // Round input data address down to 8 byte boundary
+ // NB: depending on the alignment of input[], memory
+ // before input[] will be accessed. The contents don't matter since
+ // they'll be multiplied by zero coefficients. I can't conceive of any
+ // situation where this could cause a segfault since memory protection
+ // in the x86 machines is done on much larger boundaries.
+
+ const short *ar = (short *)((unsigned long) input & ~7);
+
+ // Choose one of 4 sets of pre-shifted coefficients. al is both the
+ // index into d_aligned_taps[] and the number of 0 words padded onto
+ // that coefficients array for alignment purposes.
+
+ unsigned al = input - ar;
+
+ // call assembler routine to do the work, passing number of 2x4-float blocks.
+
+ // assert (((unsigned long) ar & 7) == 0);
+ // assert (((unsigned long) d_aligned_taps[al] & 15) == 0);
+
+ // cerr << "ar: " << ar << " d_aligned_taps[ar]: " << d_aligned_taps[al]
+ // << " (ntaps() + al - 1)/2 + 1: " << (ntaps() + al -1) / 2 + 1 << endl;
+
+ float result[2];
+
+ d_complex_dotprod (ar, d_aligned_taps[al], (ntaps() + al - 1) / 2 + 1, result);
+
+ // cerr << "result = " << result[0] << " " << result[1] << endl;
+
+ return gr_complex(result[0], result[1]);
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_scc_simd.h b/gnuradio-core/src/lib/filter/gr_fir_scc_simd.h
new file mode 100644
index 0000000000..098b02a502
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_scc_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_FIR_SCC_SIMD_H
+#define INCLUDED_GR_FIR_SCC_SIMD_H
+
+#include <gr_fir_scc_generic.h>
+
+
+/*!
+ * \brief common base class for SIMD versions of gr_fir_scc
+ *
+ * This base class handles alignment issues common to SSE and 3DNOW
+ * subclasses.
+ */
+
+class gr_fir_scc_simd : public gr_fir_scc_generic
+{
+protected:
+ typedef void (*complex_dotprod_t)(const short *input,
+ const float *taps,
+ unsigned n_2_complex_blocks,
+ float *result);
+
+ /*!
+ * \p aligned_taps holds 4 copies of the coefficients preshifted
+ * by 0, 1, 2, or 3 float pairs to meet all possible input data alignments.
+ * This allows us to always fetch data and taps that are 128-bit aligned.
+ */
+ float *d_aligned_taps[4];
+
+ complex_dotprod_t d_complex_dotprod; // fast dot product primitive
+
+public:
+
+ // CREATORS
+ gr_fir_scc_simd ();
+ gr_fir_scc_simd (const std::vector<gr_complex> &taps);
+ ~gr_fir_scc_simd ();
+
+ // MANIPULATORS
+ virtual void set_taps (const std::vector<gr_complex> &taps);
+ virtual gr_complex filter (const short input[]);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_scc_x86.cc b/gnuradio-core/src/lib/filter/gr_fir_scc_x86.cc
new file mode 100644
index 0000000000..c654fce141
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_scc_x86.h>
+#include <complex_dotprod_x86.h>
+
+/*
+ * --- 3DNow! version ---
+ */
+
+gr_fir_scc_3dnow::gr_fir_scc_3dnow ()
+ : gr_fir_scc_simd ()
+{
+ d_complex_dotprod = complex_dotprod_3dnow;
+}
+
+gr_fir_scc_3dnow::gr_fir_scc_3dnow (const std::vector<gr_complex> &new_taps)
+ : gr_fir_scc_simd (new_taps)
+{
+ d_complex_dotprod = complex_dotprod_3dnow;
+}
+
+
+/*
+ * --- 3DNow! Ext version ---
+ */
+
+gr_fir_scc_3dnowext::gr_fir_scc_3dnowext ()
+ : gr_fir_scc_simd ()
+{
+ d_complex_dotprod = complex_dotprod_3dnowext;
+}
+
+gr_fir_scc_3dnowext::gr_fir_scc_3dnowext (const std::vector<gr_complex> &new_taps)
+ : gr_fir_scc_simd (new_taps)
+{
+ d_complex_dotprod = complex_dotprod_3dnowext;
+}
+
+
+/*
+ * --- SSE version ---
+ */
+
+gr_fir_scc_sse::gr_fir_scc_sse ()
+ : gr_fir_scc_simd ()
+{
+ d_complex_dotprod = complex_dotprod_sse;
+}
+
+gr_fir_scc_sse::gr_fir_scc_sse (const std::vector<gr_complex> &new_taps)
+ : gr_fir_scc_simd (new_taps)
+{
+ d_complex_dotprod = complex_dotprod_sse;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_scc_x86.h b/gnuradio-core/src/lib/filter/gr_fir_scc_x86.h
new file mode 100644
index 0000000000..bbdf5eb7b0
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_scc_x86.h
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_FIR_SCC_X86_H
+#define INCLUDED_GR_FIR_SCC_X86_H
+
+#include <gr_fir_scc_simd.h>
+
+/*!
+ * \brief 3DNow! version of gr_fir_scc
+ */
+class gr_fir_scc_3dnow : public gr_fir_scc_simd
+{
+public:
+ gr_fir_scc_3dnow ();
+ gr_fir_scc_3dnow (const std::vector<gr_complex> &taps);
+};
+
+/*!
+ * \brief 3DNow! Ext version of gr_fir_scc
+ */
+class gr_fir_scc_3dnowext : public gr_fir_scc_simd
+{
+public:
+ gr_fir_scc_3dnowext ();
+ gr_fir_scc_3dnowext (const std::vector<gr_complex> &taps);
+};
+
+/*!
+ * \brief SSE version of gr_fir_scc
+ */
+class gr_fir_scc_sse : public gr_fir_scc_simd
+{
+public:
+ gr_fir_scc_sse ();
+ gr_fir_scc_sse (const std::vector<gr_complex> &taps);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_sysconfig_x86.cc b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_x86.cc
new file mode 100644
index 0000000000..7d576e8bbc
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_sysconfig_x86.h>
+#include <gr_cpu.h>
+
+#include <gr_fir_ccf.h>
+#include <gr_fir_ccf_generic.h>
+#include <gr_fir_ccf_x86.h>
+#include <gr_fir_fcc.h>
+#include <gr_fir_fcc_generic.h>
+#include <gr_fir_fcc_x86.h>
+#include <gr_fir_fff.h>
+#include <gr_fir_fff_generic.h>
+#include <gr_fir_fff_x86.h>
+#include <gr_fir_fsf.h>
+#include <gr_fir_fsf_generic.h>
+#include <gr_fir_fsf_x86.h>
+#include <gr_fir_ccc.h>
+#include <gr_fir_ccc_generic.h>
+#include <gr_fir_ccc_x86.h>
+#include <gr_fir_scc.h>
+#include <gr_fir_scc_generic.h>
+#include <gr_fir_scc_x86.h>
+// #include <gr_fir_sss.h>
+// #include <gr_fir_sss_generic.h>
+// #include <gr_fir_sss_mmx.h>
+// #include <gr_fir_sss_sse2.h>
+
+#include <iostream>
+using std::cerr;
+
+/*
+ * ----------------------------------------------------------------
+ * static functions that serve as constructors...
+ * Is it possible to take the address of a normal constructor?
+ * ----------------------------------------------------------------
+ */
+
+static gr_fir_ccf *
+make_gr_fir_ccf_3dnow(const std::vector<float> &taps)
+{
+ return new gr_fir_ccf_3dnow(taps);
+}
+
+static gr_fir_ccf *
+make_gr_fir_ccf_sse(const std::vector<float> &taps)
+{
+ return new gr_fir_ccf_sse(taps);
+}
+
+static gr_fir_fcc *
+make_gr_fir_fcc_3dnow(const std::vector<gr_complex> &taps)
+{
+ return new gr_fir_fcc_3dnow(taps);
+}
+
+static gr_fir_fcc *
+make_gr_fir_fcc_sse(const std::vector<gr_complex> &taps)
+{
+ return new gr_fir_fcc_sse(taps);
+}
+
+static gr_fir_ccc *
+make_gr_fir_ccc_3dnow (const std::vector<gr_complex> &taps)
+{
+ return new gr_fir_ccc_3dnow (taps);
+}
+
+static gr_fir_ccc *
+make_gr_fir_ccc_3dnowext (const std::vector<gr_complex> &taps)
+{
+ return new gr_fir_ccc_3dnowext (taps);
+}
+
+static gr_fir_ccc *
+make_gr_fir_ccc_sse (const std::vector<gr_complex> &taps)
+{
+ return new gr_fir_ccc_sse (taps);
+}
+
+static gr_fir_fff *
+make_gr_fir_fff_3dnow (const std::vector<float> &taps)
+{
+ return new gr_fir_fff_3dnow (taps);
+}
+
+static gr_fir_fff *
+make_gr_fir_fff_sse (const std::vector<float> &taps)
+{
+ return new gr_fir_fff_sse (taps);
+}
+
+static gr_fir_fsf *
+make_gr_fir_fsf_3dnow (const std::vector<float> &taps)
+{
+ return new gr_fir_fsf_3dnow (taps);
+}
+
+static gr_fir_fsf *
+make_gr_fir_fsf_sse (const std::vector<float> &taps)
+{
+ return new gr_fir_fsf_sse (taps);
+}
+
+#if 0
+static gr_fir_sss *
+make_gr_fir_sss_mmx (const std::vector<short> &taps)
+{
+ return new gr_fir_sss_mmx (taps);
+}
+
+static gr_fir_sss *
+make_gr_fir_sss_sse2 (const std::vector<short> &taps)
+{
+ return new gr_fir_sss_sse2 (taps);
+}
+#endif
+
+static gr_fir_scc *
+make_gr_fir_scc_3dnow(const std::vector<gr_complex> &taps)
+{
+ return new gr_fir_scc_3dnow(taps);
+}
+
+static gr_fir_scc *
+make_gr_fir_scc_3dnowext(const std::vector<gr_complex> &taps)
+{
+ return new gr_fir_scc_3dnowext(taps);
+}
+
+static gr_fir_scc *
+make_gr_fir_scc_sse(const std::vector<gr_complex> &taps)
+{
+ return new gr_fir_scc_sse(taps);
+}
+
+/*
+ * ----------------------------------------------------------------
+ * Return instances of the fastest x86 versions of these classes.
+ *
+ * check CPUID, if has 3DNowExt, return 3DNow!Ext version,
+ * else if 3DNow, return 3DNow! version,
+ * else if SSE2, return SSE2 version,
+ * else if SSE, return SSE version,
+ * else if MMX, return MMX version,
+ * else return generic version.
+ *
+ * FIXME: benchmark, store result, use stored result to
+ * select the fastest version.
+ * ----------------------------------------------------------------
+ */
+
+gr_fir_ccf *
+gr_fir_sysconfig_x86::create_gr_fir_ccf (const std::vector<float> &taps)
+{
+ static bool first = true;
+
+ if (gr_cpu::has_3dnow ()){
+ if (first){
+ cerr << ">>> gr_fir_ccf: using 3DNow!\n";
+ first = false;
+ }
+ return make_gr_fir_ccf_3dnow (taps);
+ }
+
+ if (gr_cpu::has_sse ()){
+ if (first){
+ cerr << ">>> gr_fir_ccf: using SSE\n";
+ first = false;
+ }
+ return make_gr_fir_ccf_sse (taps);
+ }
+
+ if (first){
+ cerr << ">>> gr_fir_ccf: handing off to parent class\n";
+ first = false;
+ }
+ return gr_fir_sysconfig_generic::create_gr_fir_ccf (taps);
+}
+
+gr_fir_fcc *
+gr_fir_sysconfig_x86::create_gr_fir_fcc (const std::vector<gr_complex> &taps)
+{
+ static bool first = true;
+
+ if (gr_cpu::has_3dnow ()){
+ if (first){
+ cerr << ">>> gr_fir_fcc: using 3DNow!\n";
+ first = false;
+ }
+ return make_gr_fir_fcc_3dnow (taps);
+ }
+
+ if (gr_cpu::has_sse ()){
+ if (first){
+ cerr << ">>> gr_fir_fcc: using SSE\n";
+ first = false;
+ }
+ return make_gr_fir_fcc_sse (taps);
+ }
+
+ if (first){
+ cerr << ">>> gr_fir_fcc: handing off to parent class\n";
+ first = false;
+ }
+ return gr_fir_sysconfig_generic::create_gr_fir_fcc (taps);
+}
+
+gr_fir_ccc *
+gr_fir_sysconfig_x86::create_gr_fir_ccc (const std::vector<gr_complex> &taps)
+{
+ static bool first = true;
+
+ if (gr_cpu::has_3dnowext ()){
+ if (first) {
+ cerr << ">>> gr_fir_ccc: using 3DNow!Ext\n";
+ first = false;
+ }
+ return make_gr_fir_ccc_3dnowext (taps);
+ }
+
+ if (gr_cpu::has_3dnow ()){
+ if (first) {
+ cerr << ">>> gr_fir_ccc: using 3DNow!\n";
+ first = false;
+ }
+ return make_gr_fir_ccc_3dnow (taps);
+ }
+
+ if (gr_cpu::has_sse ()){
+ if (first){
+ cerr << ">>> gr_fir_ccc: using SSE\n";
+ first = false;
+ }
+ return make_gr_fir_ccc_sse (taps);
+ }
+
+ if (first){
+ cerr << ">>> gr_fir_ccc: handing off to parent class\n";
+ first = false;
+ }
+ return gr_fir_sysconfig_generic::create_gr_fir_ccc (taps);
+}
+
+gr_fir_fff *
+gr_fir_sysconfig_x86::create_gr_fir_fff (const std::vector<float> &taps)
+{
+ static bool first = true;
+
+ if (gr_cpu::has_3dnow ()){
+ if (first) {
+ cerr << ">>> gr_fir_fff: using 3DNow!\n";
+ first = false;
+ }
+ return make_gr_fir_fff_3dnow (taps);
+ }
+
+ if (gr_cpu::has_sse ()){
+ if (first){
+ cerr << ">>> gr_fir_fff: using SSE\n";
+ first = false;
+ }
+ return make_gr_fir_fff_sse (taps);
+ }
+
+ if (first){
+ cerr << ">>> gr_fir_fff: handing off to parent class\n";
+ first = false;
+ }
+ return gr_fir_sysconfig_generic::create_gr_fir_fff (taps);
+}
+
+gr_fir_fsf *
+gr_fir_sysconfig_x86::create_gr_fir_fsf (const std::vector<float> &taps)
+{
+ static bool first = true;
+
+ if (gr_cpu::has_3dnow ()){
+ if (first) {
+ cerr << ">>> gr_fir_fsf: using 3DNow!\n";
+ first = false;
+ }
+ return make_gr_fir_fsf_3dnow (taps);
+ }
+
+ if (gr_cpu::has_sse ()){
+ if (first){
+ cerr << ">>> gr_fir_fsf: using SSE\n";
+ first = false;
+ }
+ return make_gr_fir_fsf_sse (taps);
+ }
+
+ if (first){
+ cerr << ">>> gr_fir_fsf: handing off to parent class\n";
+ first = false;
+ }
+ return gr_fir_sysconfig_generic::create_gr_fir_fsf (taps);
+}
+
+#if 0
+gr_fir_sss *
+gr_fir_sysconfig_x86::create_gr_fir_sss (const std::vector<short> &taps)
+{
+ // FIXME -- probably want to figure out best answer for Athlon and code
+ // add code to select it here...
+
+ if (gr_cpu::has_sse2 ()){
+ cerr << ">>> gr_fir_sss: using SSE2\n";
+ return make_gr_fir_sss_sse2 (taps);
+ }
+
+ if (gr_cpu::has_mmx ()){
+ cerr << ">>> gr_fir_sss: using MMX\n";
+ return make_gr_fir_sss_mmx (taps);
+ }
+
+ cerr << ">>> gr_fir_sss: handing off to parent class\n";
+ return gr_fir_sysconfig_generic::create_gr_fir_sss (taps);
+}
+#endif
+
+gr_fir_scc *
+gr_fir_sysconfig_x86::create_gr_fir_scc (const std::vector<gr_complex> &taps)
+{
+ static bool first = true;
+
+ if (gr_cpu::has_3dnowext ()){
+ if (first){
+ cerr << ">>> gr_fir_scc: using 3DNow!Ext\n";
+ first = false;
+ }
+ return make_gr_fir_scc_3dnowext (taps);
+ }
+
+ if (gr_cpu::has_3dnow ()){
+ if (first){
+ cerr << ">>> gr_fir_scc: using 3DNow!\n";
+ first = false;
+ }
+ return make_gr_fir_scc_3dnow (taps);
+ }
+
+ if (gr_cpu::has_sse ()){
+ if (first){
+ cerr << ">>> gr_fir_scc: using SSE\n";
+ first = false;
+ }
+ return make_gr_fir_scc_sse (taps);
+ }
+
+ if (first){
+ cerr << ">>> gr_fir_scc: handing off to parent class\n";
+ first = false;
+ }
+ return gr_fir_sysconfig_generic::create_gr_fir_scc (taps);
+}
+
+/*
+ * ----------------------------------------------------------------
+ * Return info about available implementations
+ * ----------------------------------------------------------------
+ */
+
+void
+gr_fir_sysconfig_x86::get_gr_fir_ccf_info (std::vector<gr_fir_ccf_info> *info)
+{
+ gr_fir_ccf_info t;
+
+ // invoke parent..
+ gr_fir_sysconfig_generic::get_gr_fir_ccf_info (info);
+
+ // add our stuff...
+ if (gr_cpu::has_3dnow ()){
+ t.name = "3DNow!";
+ t.create = make_gr_fir_ccf_3dnow;
+ (*info).push_back (t);
+ }
+
+ if (gr_cpu::has_sse ()){
+ t.name = "SSE";
+ t.create = make_gr_fir_ccf_sse;
+ (*info).push_back (t);
+ }
+}
+
+void
+gr_fir_sysconfig_x86::get_gr_fir_fcc_info (std::vector<gr_fir_fcc_info> *info)
+{
+ gr_fir_fcc_info t;
+
+ // invoke parent..
+ gr_fir_sysconfig_generic::get_gr_fir_fcc_info (info);
+
+ // add our stuff...
+ if (gr_cpu::has_3dnow ()){
+ t.name = "3DNow!";
+ t.create = make_gr_fir_fcc_3dnow;
+ (*info).push_back (t);
+ }
+
+ if (gr_cpu::has_sse ()){
+ t.name = "SSE";
+ t.create = make_gr_fir_fcc_sse;
+ (*info).push_back (t);
+ }
+}
+
+void
+gr_fir_sysconfig_x86::get_gr_fir_ccc_info (std::vector<gr_fir_ccc_info> *info)
+{
+ gr_fir_ccc_info t;
+
+ // invoke parent..
+ gr_fir_sysconfig_generic::get_gr_fir_ccc_info (info);
+
+ // add our stuff...
+ if (gr_cpu::has_3dnowext ()){
+ t.name = "3DNow!Ext";
+ t.create = make_gr_fir_ccc_3dnowext;
+ (*info).push_back (t);
+ }
+
+ if (gr_cpu::has_3dnow ()){
+ t.name = "3DNow!";
+ t.create = make_gr_fir_ccc_3dnow;
+ (*info).push_back (t);
+ }
+
+ if (gr_cpu::has_sse ()){
+ t.name = "SSE";
+ t.create = make_gr_fir_ccc_sse;
+ (*info).push_back (t);
+ }
+}
+
+void
+gr_fir_sysconfig_x86::get_gr_fir_fff_info (std::vector<gr_fir_fff_info> *info)
+{
+ gr_fir_fff_info t;
+
+ // invoke parent..
+ gr_fir_sysconfig_generic::get_gr_fir_fff_info (info);
+
+ // add our stuff...
+ if (gr_cpu::has_3dnow ()){
+ t.name = "3DNow!";
+ t.create = make_gr_fir_fff_3dnow;
+ (*info).push_back (t);
+ }
+
+ if (gr_cpu::has_sse ()){
+ t.name = "SSE";
+ t.create = make_gr_fir_fff_sse;
+ (*info).push_back (t);
+ }
+}
+
+void
+gr_fir_sysconfig_x86::get_gr_fir_fsf_info (std::vector<gr_fir_fsf_info> *info)
+{
+ gr_fir_fsf_info t;
+
+ // invoke parent..
+ gr_fir_sysconfig_generic::get_gr_fir_fsf_info (info);
+
+ // add our stuff...
+ if (gr_cpu::has_3dnow ()){
+ t.name = "3DNow!";
+ t.create = make_gr_fir_fsf_3dnow;
+ (*info).push_back (t);
+ }
+
+ if (gr_cpu::has_sse ()){
+ t.name = "SSE";
+ t.create = make_gr_fir_fsf_sse;
+ (*info).push_back (t);
+ }
+}
+
+void
+gr_fir_sysconfig_x86::get_gr_fir_scc_info (std::vector<gr_fir_scc_info> *info)
+{
+ gr_fir_scc_info t;
+
+ // invoke parent..
+ gr_fir_sysconfig_generic::get_gr_fir_scc_info (info);
+
+ // add our stuff...
+ if (gr_cpu::has_3dnowext ()){
+ t.name = "3DNow!Ext";
+ t.create = make_gr_fir_scc_3dnowext;
+ (*info).push_back (t);
+ }
+
+ if (gr_cpu::has_3dnow ()){
+ t.name = "3DNow!";
+ t.create = make_gr_fir_scc_3dnow;
+ (*info).push_back (t);
+ }
+
+ if (gr_cpu::has_sse ()){
+ t.name = "SSE";
+ t.create = make_gr_fir_scc_sse;
+ (*info).push_back (t);
+ }
+}
+
+#if 0
+void
+gr_fir_sysconfig_x86::get_gr_fir_sss_info (std::vector<gr_fir_sss_info> *info)
+{
+ gr_fir_sss_info t;
+
+ // invoke parent..
+ gr_fir_sysconfig_generic::get_gr_fir_sss_info (info);
+
+ // add our stuff...
+ if (gr_cpu::has_mmx ()){
+ t.name = "MMX";
+ t.create = make_gr_fir_sss_mmx;
+ (*info).push_back (t);
+ }
+
+ if (gr_cpu::has_sse2 ()){
+ t.name = "SSE2";
+ t.create = make_gr_fir_sss_sse2;
+ (*info).push_back (t);
+ }
+}
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_sysconfig_x86.h b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_x86.h
new file mode 100644
index 0000000000..2f1d48efd6
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_FIR_SYSCONFIG_X86_H
+#define INCLUDED_GR_FIR_SYSCONFIG_X86_H
+
+#include <gr_fir_sysconfig_generic.h>
+
+class gr_fir_sysconfig_x86 : public gr_fir_sysconfig_generic {
+public:
+ virtual gr_fir_ccf *create_gr_fir_ccf (const std::vector<float> &taps);
+ virtual gr_fir_fcc *create_gr_fir_fcc (const std::vector<gr_complex> &taps);
+ virtual gr_fir_fff *create_gr_fir_fff (const std::vector<float> &taps);
+ virtual gr_fir_fsf *create_gr_fir_fsf (const std::vector<float> &taps);
+ virtual gr_fir_scc *create_gr_fir_scc (const std::vector<gr_complex> &taps);
+ virtual gr_fir_ccc *create_gr_fir_ccc (const std::vector<gr_complex> &taps);
+//virtual gr_fir_sss *create_gr_fir_sss (const std::vector<short> &taps);
+
+ virtual void get_gr_fir_ccf_info (std::vector<gr_fir_ccf_info> *info);
+ virtual void get_gr_fir_fcc_info (std::vector<gr_fir_fcc_info> *info);
+ virtual void get_gr_fir_fff_info (std::vector<gr_fir_fff_info> *info);
+ virtual void get_gr_fir_fsf_info (std::vector<gr_fir_fsf_info> *info);
+ virtual void get_gr_fir_scc_info (std::vector<gr_fir_scc_info> *info);
+ virtual void get_gr_fir_ccc_info (std::vector<gr_fir_ccc_info> *info);
+//virtual void get_gr_fir_sss_info (std::vector<gr_fir_sss_info> *info);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fractional_interpolator.cc b/gnuradio-core/src/lib/filter/gr_fractional_interpolator.cc
new file mode 100644
index 0000000000..6abb963d94
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fractional_interpolator.cc
@@ -0,0 +1,97 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_io_signature.h>
+#include <gr_fractional_interpolator.h>
+#include <gri_mmse_fir_interpolator.h>
+#include <stdexcept>
+
+// Public constructor
+gr_fractional_interpolator_sptr gr_make_fractional_interpolator(float phase_shift, float interp_ratio)
+{
+ return gr_fractional_interpolator_sptr(new gr_fractional_interpolator(phase_shift, interp_ratio));
+}
+
+gr_fractional_interpolator::gr_fractional_interpolator(float phase_shift, float interp_ratio)
+ : gr_block ("fractional_interpolator",
+ gr_make_io_signature (1, 1, sizeof (float)),
+ gr_make_io_signature (1, 1, sizeof (float))),
+ d_mu (phase_shift), d_mu_inc (interp_ratio), d_interp()
+{
+ if (interp_ratio <= 0)
+ throw std::out_of_range ("interpolation ratio must be > 0");
+ if (phase_shift < 0 || phase_shift > 1)
+ throw std::out_of_range ("phase shift ratio must be > 0 and < 1");
+
+ set_relative_rate (1.0 / interp_ratio);
+}
+
+gr_fractional_interpolator::~gr_fractional_interpolator()
+{
+ delete d_interp;
+}
+
+void
+gr_fractional_interpolator::forecast(int noutput_items, gr_vector_int &ninput_items_required)
+{
+ unsigned ninputs = ninput_items_required.size();
+ for (unsigned i=0; i < ninputs; i++)
+
+ ninput_items_required[i] =
+ (int) ceil((noutput_items * d_mu_inc) + d_interp->ntaps());
+}
+
+int
+gr_fractional_interpolator::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+ float *out = (float *) output_items[0];
+
+ int ii = 0; // input index
+ int oo = 0; // output index
+
+ while (oo < noutput_items){
+
+ // produce output sample
+
+ out[oo++] = d_interp->interpolate(&in[ii], d_mu);
+
+ // printf( "%4d %9.6f\n", ii, d_mu);
+
+ double s = d_mu + d_mu_inc;
+ double f = floor (s);
+ int incr = (int) f;
+ d_mu = s - f;
+ ii += incr;
+ }
+
+ consume_each (ii);
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fractional_interpolator.h b/gnuradio-core/src/lib/filter/gr_fractional_interpolator.h
new file mode 100644
index 0000000000..b024c44162
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fractional_interpolator.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_FRACTIONAL_INTERPOLATOR_H
+#define INCLUDED_GR_FRACTIONAL_INTERPOLATOR_H
+
+#include <gr_block.h>
+
+class gri_mmse_fir_interpolator;
+
+class gr_fractional_interpolator;
+typedef boost::shared_ptr<gr_fractional_interpolator> gr_fractional_interpolator_sptr;
+
+// public constructor
+gr_fractional_interpolator_sptr gr_make_fractional_interpolator (float phase_shift, float interp_ratio);
+
+/*!
+ * \brief Interpolating mmse filter with float input, float output
+ * \ingroup filter
+ */
+class gr_fractional_interpolator : public gr_block
+{
+ public:
+ ~gr_fractional_interpolator ();
+ void forecast(int noutput_items, gr_vector_int &ninput_items_required);
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+protected:
+ gr_fractional_interpolator (float phase_shift, float interp_ratio);
+
+ private:
+ float d_mu;
+ float d_mu_inc;
+ gri_mmse_fir_interpolator *d_interp;
+
+ friend gr_fractional_interpolator_sptr
+ gr_make_fractional_interpolator (float phase_shift, float interp_ratio);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.cc.t b/gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.cc.t
new file mode 100644
index 0000000000..4592e754e0
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.cc.t
@@ -0,0 +1,122 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * WARNING: This file is automatically generated by
+ * generate_gr_freq_xlating_fir_filter_XXX.py
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <@FIR_TYPE@.h>
+#include <gr_fir_util.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps,
+ double center_freq, double sampling_freq)
+{
+ return @SPTR_NAME@ (new @NAME@ (decimation, taps, center_freq, sampling_freq));
+}
+
+
+@NAME@::@NAME@ (
+
+ int decimation,
+ const std::vector<@TAP_TYPE@> &taps,
+ double center_freq,
+ double sampling_freq)
+
+ : gr_sync_decimator ("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@)),
+ decimation),
+ d_proto_taps (taps), d_center_freq (center_freq), d_sampling_freq (sampling_freq),
+ d_updated (false)
+{
+ std::vector<gr_complex> dummy_taps;
+ d_composite_fir = gr_fir_util::create_@FIR_TYPE@ (dummy_taps);
+
+ set_history (d_proto_taps.size ());
+ build_composite_fir ();
+}
+
+@NAME@::~@NAME@ ()
+{
+ delete d_composite_fir;
+}
+
+void
+@NAME@::build_composite_fir ()
+{
+ std::vector<gr_complex> ctaps (d_proto_taps.size ());
+
+ float fwT0 = 2 * M_PI * d_center_freq / d_sampling_freq;
+ for (unsigned int i = 0; i < d_proto_taps.size (); i++)
+ ctaps[i] = d_proto_taps[i] * exp (gr_complex (0, i * fwT0));
+
+ d_composite_fir->set_taps (gr_reverse(ctaps));
+ d_r.set_phase_incr (exp (gr_complex (0, fwT0 * decimation ())));
+}
+
+void
+@NAME@::set_center_freq (double center_freq)
+{
+ d_center_freq = center_freq;
+ d_updated = true;
+}
+
+void
+@NAME@::set_taps (const std::vector<@TAP_TYPE@> &taps)
+{
+ d_proto_taps = taps;
+ d_updated = true;
+}
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ @I_TYPE@ *in = (@I_TYPE@ *) input_items[0];
+ @O_TYPE@ *out = (@O_TYPE@ *) output_items[0];
+
+ // rebuild composite FIR if the center freq has changed
+
+ if (d_updated){
+ set_history (d_proto_taps.size ());
+ build_composite_fir ();
+ d_updated = false;
+ }
+
+ unsigned j = 0;
+ for (int i = 0; i < noutput_items; i++){
+ out[i] = d_r.rotate (d_composite_fir->filter (&in[j]));
+ j += decimation ();
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.h.t b/gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.h.t
new file mode 100644
index 0000000000..d1351e20ee
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.h.t
@@ -0,0 +1,100 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * WARNING: This file is automatically generated by
+ * generate_gr_freq_xlating_fir_filter_XXX.py Any changes made to this file
+ * will be overwritten.
+ */
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_decimator.h>
+#include <gr_rotator.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+/*!
+ * Construct a FIR filter with the given taps and a composite frequency
+ * translation that shifts center_freq down to zero Hz. The frequency
+ * translation logically comes before the filtering operation.
+ */
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps,
+ double center_freq, double sampling_freq);
+
+
+class @FIR_TYPE@;
+
+/*!
+ * \brief FIR filter combined with frequency translation with @I_TYPE@ input, @O_TYPE@ output and @TAP_TYPE@ taps
+ * \ingroup filter
+ *
+ * This class efficiently combines a frequency translation
+ * (typically "down conversion") with a FIR filter (typically low-pass)
+ * and decimation. It is ideally suited for a "channel selection filter"
+ * and can be efficiently used to select and decimate a narrow band signal
+ * out of wide bandwidth input.
+ *
+ * Uses a single input array to produce a single output array.
+ * Additional inputs and/or outputs are ignored.
+ */
+class @NAME@ : public gr_sync_decimator
+{
+ public:
+ virtual ~@NAME@ ();
+
+ void set_center_freq (double center_freq);
+ void set_taps (const std::vector<@TAP_TYPE@> &taps);
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ private:
+ friend @SPTR_NAME@
+ gr_make_@BASE_NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps,
+ double center_freq, double sampling_freq);
+
+ protected:
+ std::vector<@TAP_TYPE@> d_proto_taps;
+ @FIR_TYPE@ *d_composite_fir;
+ gr_rotator d_r;
+ double d_center_freq;
+ double d_sampling_freq;
+ bool d_updated;
+
+ virtual void build_composite_fir ();
+
+ /*!
+ * Construct a FIR filter with the given taps and a composite frequency
+ * translation that shifts center_freq down to zero Hz. The frequency
+ * translation logically comes before the filtering operation.
+ */
+ @NAME@ (int decimation,
+ const std::vector<@TAP_TYPE@> &taps,
+ double center_freq, double sampling_freq);
+};
+
+#endif /* _@NAME@_H_ */
diff --git a/gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.i.t b/gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.i.t
new file mode 100644
index 0000000000..0a4f8b316a
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * WARNING: This file is automatically generated by
+ * generate_gr_freq_xlating_fir_filter_XXX.py
+ * Any changes made to this file will be overwritten.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps,
+ double center_freq, double sampling_freq);
+
+
+class @NAME@ : public gr_sync_decimator
+{
+ protected:
+ @NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps,
+ double center_freq, double sampling_freq);
+
+ public:
+ ~@NAME@ ();
+
+ void set_center_freq (double center_freq);
+ void set_taps (const std::vector<@TAP_TYPE@> &taps);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_goertzel_fc.cc b/gnuradio-core/src/lib/filter/gr_goertzel_fc.cc
new file mode 100644
index 0000000000..264b96e672
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_goertzel_fc.cc
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_goertzel_fc.h>
+#include <gr_io_signature.h>
+
+// public constructor
+gr_goertzel_fc_sptr
+gr_make_goertzel_fc(int rate, int len, float freq)
+{
+ return gr_goertzel_fc_sptr (new gr_goertzel_fc(rate, len, freq));
+}
+
+gr_goertzel_fc::gr_goertzel_fc(int rate, int len, float freq)
+ : gr_sync_decimator("goertzel_fc",
+ gr_make_io_signature (1, 1, sizeof (float)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ len),
+ d_goertzel(rate, len, freq)
+{
+ d_len = len;
+}
+
+int gr_goertzel_fc::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ float *in = (float *)input_items[0];
+ gr_complex *out = (gr_complex *)output_items[0];
+
+ for (int i = 0; i < noutput_items; i++) {
+ *out++ = d_goertzel.batch(in);
+ in += d_len;
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_goertzel_fc.h b/gnuradio-core/src/lib/filter/gr_goertzel_fc.h
new file mode 100644
index 0000000000..c8363bc473
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_goertzel_fc.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_GOERTZEL_FC_H
+#define INCLUDED_GR_GOERTZEL_FC_H
+
+#include <gri_goertzel.h>
+#include <gr_sync_decimator.h>
+
+class gr_goertzel_fc;
+typedef boost::shared_ptr<gr_goertzel_fc> gr_goertzel_fc_sptr;
+
+// public constructor
+gr_goertzel_fc_sptr gr_make_goertzel_fc(int rate, int len, float freq);
+
+/*!
+ * \brief Goertzel single-bin DFT calculation.
+ * \ingroup filter
+ */
+class gr_goertzel_fc : public gr_sync_decimator
+{
+private:
+ friend gr_goertzel_fc_sptr gr_make_goertzel_fc (int rate, int len, float freq);
+
+ gr_goertzel_fc(int rate, int len, float freq);
+ gri_goertzel d_goertzel;
+ int d_len;
+
+public:
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_GOERTZEL_FC_H */
+
diff --git a/gnuradio-core/src/lib/filter/gr_goertzel_fc.i b/gnuradio-core/src/lib/filter/gr_goertzel_fc.i
new file mode 100644
index 0000000000..6d5efd2332
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_goertzel_fc.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,goertzel_fc);
+
+gr_goertzel_fc_sptr gr_make_goertzel_fc(int rate, int len, float freq);
+
+class gr_goertzel_fc : public gr_sync_decimator
+{
+private:
+ gr_goertzel_fc();
+};
diff --git a/gnuradio-core/src/lib/filter/gr_hilbert_fc.cc b/gnuradio-core/src/lib/filter/gr_hilbert_fc.cc
new file mode 100644
index 0000000000..371363c38e
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_hilbert_fc.cc
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_hilbert_fc.h>
+#include <gr_firdes.h>
+#include <gr_fir_fff.h>
+#include <gr_fir_util.h>
+
+// public constructor
+gr_hilbert_fc_sptr
+gr_make_hilbert_fc (unsigned int ntaps)
+{
+ return gr_hilbert_fc_sptr (new gr_hilbert_fc (ntaps));
+}
+
+gr_hilbert_fc::gr_hilbert_fc (unsigned int ntaps)
+ : gr_sync_block ("hilbert_fc",
+ gr_make_io_signature (1, 1, sizeof (float)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex))),
+ d_ntaps (ntaps | 0x1), // ensure ntaps is odd
+ d_hilb (gr_fir_util::create_gr_fir_fff (gr_firdes::hilbert (d_ntaps)))
+{
+ set_history (d_ntaps);
+}
+
+gr_hilbert_fc::~gr_hilbert_fc ()
+{
+ delete d_hilb;
+}
+
+int
+gr_hilbert_fc::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ float *in = (float *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ for (int i = 0; i < noutput_items; i++)
+ out[i] = gr_complex (in[i + d_ntaps/2],
+ d_hilb->filter (&in[i]));
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_hilbert_fc.h b/gnuradio-core/src/lib/filter/gr_hilbert_fc.h
new file mode 100644
index 0000000000..54082a95e1
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_hilbert_fc.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_HILBERT_FC_H
+#define INCLUDED_GR_HILBERT_FC_H
+
+#include <gr_sync_block.h>
+#include <gr_io_signature.h>
+#include <gr_types.h>
+
+class gr_hilbert_fc;
+typedef boost::shared_ptr<gr_hilbert_fc> gr_hilbert_fc_sptr;
+
+// public constructor
+gr_hilbert_fc_sptr gr_make_hilbert_fc (unsigned int ntaps);
+
+
+class gr_fir_fff;
+
+/*!
+ * \brief Hilbert transformer.
+ * \ingroup filter
+ *
+ * real output is input appropriately delayed.
+ * imaginary output is hilbert filtered (90 degree phase shift)
+ * version of input.
+ */
+class gr_hilbert_fc : public gr_sync_block
+{
+ public:
+ ~gr_hilbert_fc ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ protected:
+ gr_hilbert_fc (unsigned int ntaps);
+
+ private:
+ unsigned int d_ntaps;
+ gr_fir_fff *d_hilb;
+
+ friend gr_hilbert_fc_sptr gr_make_hilbert_fc (unsigned int ntaps);
+};
+
+
+
+#endif /* INCLUDED_GR_HILBERT_FC_H */
diff --git a/gnuradio-core/src/lib/filter/gr_hilbert_fc.i b/gnuradio-core/src/lib/filter/gr_hilbert_fc.i
new file mode 100644
index 0000000000..f69f624aea
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,hilbert_fc);
+
+gr_hilbert_fc_sptr gr_make_hilbert_fc (unsigned int ntaps);
+
+class gr_hilbert_fc : public gr_sync_block
+{
+protected:
+ gr_hilbert_fc (unsigned int ntaps);
+
+public:
+ ~gr_hilbert_fc ();
+};
diff --git a/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.cc b/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.cc
new file mode 100644
index 0000000000..4e825e7a89
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_iir_filter_ffd.h>
+#include <gr_io_signature.h>
+#include <stdio.h>
+
+
+gr_iir_filter_ffd_sptr
+gr_make_iir_filter_ffd (const std::vector<double> &fftaps,
+ const std::vector<double> &fbtaps) throw (std::invalid_argument)
+{
+ return gr_iir_filter_ffd_sptr (new gr_iir_filter_ffd (fftaps, fbtaps));
+}
+
+gr_iir_filter_ffd::gr_iir_filter_ffd (const std::vector<double> &fftaps,
+ const std::vector<double> &fbtaps) throw (std::invalid_argument)
+
+ : gr_sync_block ("iir_filter_ffd",
+ gr_make_io_signature (1, 1, sizeof (float)),
+ gr_make_io_signature (1, 1, sizeof (float))),
+ d_iir (fftaps, fbtaps),
+ d_updated (false)
+{
+ // fprintf (stderr, "gr_iir_filter_ffd::ctor\n");
+}
+
+gr_iir_filter_ffd::~gr_iir_filter_ffd ()
+{
+ // nop
+}
+
+void
+gr_iir_filter_ffd::set_taps (const std::vector<double> &fftaps,
+ const std::vector<double> &fbtaps) throw (std::invalid_argument)
+{
+ if (fftaps.size () != fbtaps.size ()){
+ fprintf (stderr,
+ "gr_iir_filter_ffd::set_taps: fftaps and fbtaps must have the same number of elements.\n");
+ throw std::invalid_argument ("gr_iir_filter_ffd::set_taps");
+ }
+
+ d_new_fftaps = fftaps;
+ d_new_fbtaps = fbtaps;
+ d_updated = true;
+}
+
+int
+gr_iir_filter_ffd::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+ float *out = (float *) output_items[0];
+
+ // fprintf (stderr, "gr_iir_filter_ffd::work noutput_items = %d\n", noutput_items);
+
+ if (d_updated){
+ d_iir.set_taps (d_new_fftaps, d_new_fbtaps);
+ d_updated = false;
+ }
+
+ d_iir.filter_n (out, in, noutput_items);
+ return noutput_items;
+};
diff --git a/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.h b/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.h
new file mode 100644
index 0000000000..5ef36349e1
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_IIR_FILTER_FFD_H
+#define INCLUDED_GR_IIR_FILTER_FFD_H
+
+#include <gr_sync_block.h>
+#include <gri_iir.h>
+#include <stdexcept>
+
+class gr_iir_filter_ffd;
+typedef boost::shared_ptr<gr_iir_filter_ffd> gr_iir_filter_ffd_sptr;
+gr_iir_filter_ffd_sptr
+gr_make_iir_filter_ffd (const std::vector<double> &fftaps,
+ const std::vector<double> &fbtaps) throw (std::invalid_argument);
+
+/*!
+ * \brief IIR filter with float input, float output and double taps
+ * \ingroup filter
+ *
+ * This filter uses the Direct Form I implementation, where
+ * \p fftaps contains the feed-forward taps, and \p fbtaps the feedback ones.
+ *
+ * \p fftaps and \p fbtaps must have equal numbers of taps
+ *
+ * The input and output satisfy a difference equation of the form
+
+ \f[
+ y[n] - \sum_{k=1}^{N} a_k y[n-k] = \sum_{k=0}^{M} b_k x[n-k]
+ \f]
+
+ * with the corresponding rational system function
+
+ \f[
+ H(z) = \frac{\sum_{k=0}^{M} b_k z^{-k}}{1 - \sum_{k=1}^{N} a_k z^{-k}}
+ \f]
+
+ * Note that some texts define the system function with a + in the denominator.
+ * If you're using that convention, you'll need to negate the feedback taps.
+ */
+class gr_iir_filter_ffd : public gr_sync_block
+{
+ private:
+ friend gr_iir_filter_ffd_sptr
+ gr_make_iir_filter_ffd (const std::vector<double> &fftaps,
+ const std::vector<double> &fbtaps) throw (std::invalid_argument);
+
+ gri_iir<float,float,double> d_iir;
+ std::vector<double> d_new_fftaps;
+ std::vector<double> d_new_fbtaps;
+ bool d_updated;
+
+ /*!
+ * Construct an IIR filter with the given taps
+ */
+ gr_iir_filter_ffd (const std::vector<double> &fftaps,
+ const std::vector<double> &fbtaps) throw (std::invalid_argument);
+
+ public:
+ ~gr_iir_filter_ffd ();
+
+ void set_taps (const std::vector<double> &fftaps,
+ const std::vector<double> &fbtaps) throw (std::invalid_argument);
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.i b/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.i
new file mode 100644
index 0000000000..bab8310fec
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,iir_filter_ffd);
+
+gr_iir_filter_ffd_sptr
+gr_make_iir_filter_ffd (const std::vector<double> &fftaps,
+ const std::vector<double> &fbtaps) throw (std::invalid_argument);
+
+class gr_iir_filter_ffd : public gr_sync_block
+{
+ private:
+ gr_iir_filter_ffd (const std::vector<double> &fftaps,
+ const std::vector<double> &fbtaps) throw (std::invalid_argument);
+
+ public:
+ ~gr_iir_filter_ffd ();
+
+ void set_taps (const std::vector<double> &fftaps,
+ const std::vector<double> &fbtaps) throw (std::invalid_argument);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_interp_fir_filter_XXX.cc.t b/gnuradio-core/src/lib/filter/gr_interp_fir_filter_XXX.cc.t
new file mode 100644
index 0000000000..f382a7cd04
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_interp_fir_filter_XXX.cc.t
@@ -0,0 +1,146 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * WARNING: This file is automatically generated by generate_gr_fir_filter_XXX.py
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <@FIR_TYPE@.h>
+#include <gr_fir_util.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <iostream>
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (unsigned interpolation, const std::vector<@TAP_TYPE@> &taps)
+{
+ return @SPTR_NAME@ (new @NAME@ (interpolation, taps));
+}
+
+
+@NAME@::@NAME@ (unsigned interpolation, const std::vector<@TAP_TYPE@> &taps)
+ : gr_sync_interpolator ("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@)),
+ interpolation),
+ d_updated (false), d_firs (interpolation)
+{
+ if (interpolation == 0)
+ throw std::out_of_range ("interpolation must be > 0");
+
+ std::vector<@TAP_TYPE@> dummy_taps;
+
+ for (unsigned i = 0; i < interpolation; i++)
+ d_firs[i] = gr_fir_util::create_@FIR_TYPE@ (dummy_taps);
+
+ set_taps (taps);
+ install_taps(d_new_taps);
+}
+
+@NAME@::~@NAME@ ()
+{
+ int interp = interpolation ();
+ for (int i = 0; i < interp; i++)
+ delete d_firs[i];
+}
+
+void
+@NAME@::set_taps (const std::vector<@TAP_TYPE@> &taps)
+{
+ d_new_taps = taps;
+ d_updated = true;
+
+ // round up length to a multiple of the interpolation factor
+ int n = taps.size () % interpolation ();
+ if (n > 0){
+ n = interpolation () - n;
+ while (n-- > 0)
+ d_new_taps.insert(d_new_taps.begin(), 0);
+ }
+
+ assert (d_new_taps.size () % interpolation () == 0);
+}
+
+
+void
+@NAME@::install_taps (const std::vector<@TAP_TYPE@> &taps)
+{
+ int nfilters = interpolation ();
+ int nt = taps.size () / nfilters;
+
+ assert (nt * nfilters == (int) taps.size ());
+
+ std::vector< std::vector <@TAP_TYPE@> > xtaps (nfilters);
+
+ for (int n = 0; n < nfilters; n++)
+ xtaps[n].resize (nt);
+
+ for (int i = 0; i < (int) taps.size(); i++)
+ xtaps[i % nfilters][i / nfilters] = taps[i];
+
+ for (int n = 0; n < nfilters; n++)
+ d_firs[n]->set_taps (xtaps[n]);
+
+ set_history (nt);
+ d_updated = false;
+
+#if 0
+ for (int i = 0; i < nfilters; i++){
+ std::cout << "filter[" << i << "] = ";
+ for (int j = 0; j < nt; j++)
+ std::cout << xtaps[i][j] << " ";
+
+ std::cout << "\n";
+ }
+#endif
+
+}
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const @I_TYPE@ *in = (const @I_TYPE@ *) input_items[0];
+ @O_TYPE@ *out = (@O_TYPE@ *) output_items[0];
+
+ if (d_updated) {
+ install_taps (d_new_taps);
+ return 0; // history requirements may have changed.
+ }
+
+ int nfilters = interpolation ();
+ int ni = noutput_items / interpolation ();
+
+ for (int i = 0; i < ni; i++){
+ for (int nf = 0; nf < nfilters; nf++)
+ out[nf] = d_firs[nf]->filter (&in[i]);
+ out += nfilters;
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_interp_fir_filter_XXX.h.t b/gnuradio-core/src/lib/filter/gr_interp_fir_filter_XXX.h.t
new file mode 100644
index 0000000000..866c43ab21
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_interp_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * WARNING: This file is automatically generated by generate_gr_fir_filter_XXX.py
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_interpolator.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+@SPTR_NAME@ gr_make_@BASE_NAME@ (unsigned interpolation, const std::vector<@TAP_TYPE@> &taps);
+
+class @FIR_TYPE@;
+
+/*!
+ * \brief Interpolating FIR filter with @I_TYPE@ input, @O_TYPE@ output and @TAP_TYPE@ taps
+ * \ingroup filter
+ */
+class @NAME@ : public gr_sync_interpolator
+{
+ private:
+ friend @SPTR_NAME@ gr_make_@BASE_NAME@ (unsigned interpolation, const std::vector<@TAP_TYPE@> &taps);
+
+ std::vector<@TAP_TYPE@> d_new_taps;
+ bool d_updated;
+ std::vector<@FIR_TYPE@ *> d_firs;
+
+ /*!
+ * Construct a FIR filter with the given taps
+ */
+ @NAME@ (unsigned interpolation, const std::vector<@TAP_TYPE@> &taps);
+
+ void install_taps (const std::vector<@TAP_TYPE@> &taps);
+
+ public:
+ ~@NAME@ ();
+
+ void set_taps (const std::vector<@TAP_TYPE@> &taps);
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_interp_fir_filter_XXX.i.t b/gnuradio-core/src/lib/filter/gr_interp_fir_filter_XXX.i.t
new file mode 100644
index 0000000000..d58c823f74
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * WARNING: This file is automatically generated by generate_GrFIRfilterXXX.py
+ * Any changes made to this file will be overwritten.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (int interpolation, const std::vector<@TAP_TYPE@> &taps);
+
+class @NAME@ : public gr_sync_interpolator
+{
+ private:
+ @NAME@ (int interpolation, const std::vector<@TAP_TYPE@> &taps);
+
+ public:
+ ~@NAME@ ();
+
+ void set_taps (const std::vector<@TAP_TYPE@> &taps);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_rational_resampler_base_XXX.cc.t b/gnuradio-core/src/lib/filter/gr_rational_resampler_base_XXX.cc.t
new file mode 100644
index 0000000000..a07b739ef9
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_rational_resampler_base_XXX.cc.t
@@ -0,0 +1,172 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * WARNING: This file is automatically generated by
+ * generate_gr_rational_resampler_base_XXX.py Any changes made to this
+ * file will be overwritten.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <@FIR_TYPE@.h>
+#include <gr_fir_util.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <iostream>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (unsigned interpolation,
+ unsigned decimation,
+ const std::vector<@TAP_TYPE@> &taps)
+{
+ return @SPTR_NAME@ (new @NAME@ (interpolation, decimation, taps));
+}
+
+@NAME@::@NAME@ (unsigned interpolation, unsigned decimation,
+ const std::vector<@TAP_TYPE@> &taps)
+ : gr_block ("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@))),
+ d_history(1),
+ d_interpolation(interpolation), d_decimation(decimation),
+ d_ctr(0), d_updated(false),
+ d_firs(interpolation)
+{
+ if (interpolation == 0)
+ throw std::out_of_range ("interpolation must be > 0");
+ if (decimation == 0)
+ throw std::out_of_range ("decimation must be > 0");
+
+ set_relative_rate (1.0 * interpolation / decimation);
+ set_output_multiple (1);
+
+ std::vector<@TAP_TYPE@> dummy_taps;
+
+ for (unsigned i = 0; i < interpolation; i++)
+ d_firs[i] = gr_fir_util::create_@FIR_TYPE@ (dummy_taps);
+
+ set_taps (taps);
+ install_taps (d_new_taps);
+}
+
+@NAME@::~@NAME@ ()
+{
+ int interp = interpolation();
+ for (int i = 0; i < interp; i++)
+ delete d_firs[i];
+}
+
+void
+@NAME@::set_taps (const std::vector<@TAP_TYPE@> &taps)
+{
+ d_new_taps = taps;
+ d_updated = true;
+
+ // round up length to a multiple of the interpolation factor
+ int n = taps.size () % interpolation ();
+ if (n > 0){
+ n = interpolation () - n;
+ while (n-- > 0)
+ d_new_taps.insert(d_new_taps.begin(), 0);
+ }
+
+ assert (d_new_taps.size () % interpolation () == 0);
+}
+
+
+void
+@NAME@::install_taps (const std::vector<@TAP_TYPE@> &taps)
+{
+ int nfilters = interpolation ();
+ int nt = taps.size () / nfilters;
+
+ assert (nt * nfilters == (int) taps.size ());
+
+ std::vector< std::vector <@TAP_TYPE@> > xtaps (nfilters);
+
+ for (int n = 0; n < nfilters; n++)
+ xtaps[n].resize (nt);
+
+ for (int i = 0; i < (int) taps.size(); i++)
+ xtaps[i % nfilters][i / nfilters] = taps[i];
+
+ for (int n = 0; n < nfilters; n++)
+ d_firs[n]->set_taps (xtaps[n]);
+
+ set_history (nt);
+ d_updated = false;
+
+#if 0
+ for (int i = 0; i < nfilters; i++){
+ std::cout << "filter[" << i << "] = ";
+ for (int j = 0; j < nt; j++)
+ std::cout << xtaps[i][j] << " ";
+
+ std::cout << "\n";
+ }
+#endif
+
+}
+
+void
+@NAME@::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+ int nreqd = std::max((unsigned)1, (int)((double) (noutput_items+1) * decimation() / interpolation()) + history() - 1);
+ unsigned ninputs = ninput_items_required.size ();
+ for (unsigned i = 0; i < ninputs; i++)
+ ninput_items_required[i] = nreqd;
+}
+
+int
+@NAME@::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const @I_TYPE@ *in = (const @I_TYPE@ *) input_items[0];
+ @O_TYPE@ *out = (@O_TYPE@ *) output_items[0];
+
+ if (d_updated) {
+ install_taps (d_new_taps);
+ return 0; // history requirement may have increased.
+ }
+
+ unsigned int ctr = d_ctr;
+
+ int i = 0;
+ while (i < noutput_items){
+ out[i++] = d_firs[ctr]->filter(in);
+ ctr += decimation();
+ while (ctr >= interpolation()){
+ ctr -= interpolation();
+ in++;
+ }
+ }
+
+ d_ctr = ctr;
+ consume_each(in - (@I_TYPE@ *) input_items[0]);
+ return i;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_rational_resampler_base_XXX.h.t b/gnuradio-core/src/lib/filter/gr_rational_resampler_base_XXX.h.t
new file mode 100644
index 0000000000..011726935d
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_rational_resampler_base_XXX.h.t
@@ -0,0 +1,87 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * WARNING: This file is automatically generated by
+ * generate_gr_rational_resampler_base_XXX.py Any changes made to this
+ * file will be overwritten.
+ */
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (unsigned interpolation,
+ unsigned decimation,
+ const std::vector<@TAP_TYPE@> &taps);
+
+class @FIR_TYPE@;
+
+/*!
+ * \brief Rational Resampling Polyphase FIR filter with @I_TYPE@ input, @O_TYPE@ output and @TAP_TYPE@ taps
+ * \ingroup filter
+ */
+class @NAME@ : public gr_block
+{
+ private:
+ unsigned d_history;
+ unsigned d_interpolation, d_decimation;
+ unsigned d_ctr;
+ std::vector<@TAP_TYPE@> d_new_taps;
+ bool d_updated;
+ std::vector<@FIR_TYPE@ *> d_firs;
+
+ friend @SPTR_NAME@
+ gr_make_@BASE_NAME@ (unsigned interpolation, unsigned decimation, const std::vector<@TAP_TYPE@> &taps);
+
+
+ /*!
+ * Construct a FIR filter with the given taps
+ */
+ @NAME@ (unsigned interpolation, unsigned decimation,
+ const std::vector<@TAP_TYPE@> &taps);
+
+ void install_taps (const std::vector<@TAP_TYPE@> &taps);
+
+ public:
+ ~@NAME@ ();
+ unsigned history () const { return d_history; }
+ void set_history (unsigned history) { d_history = history; }
+
+ unsigned interpolation() const { return d_interpolation; }
+ unsigned decimation() const { return d_decimation; }
+
+ void set_taps (const std::vector<@TAP_TYPE@> &taps);
+
+ void forecast (int noutput_items, gr_vector_int &ninput_items_required);
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_rational_resampler_base_XXX.i.t b/gnuradio-core/src/lib/filter/gr_rational_resampler_base_XXX.i.t
new file mode 100644
index 0000000000..2411d0347b
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * WARNING: This file is automatically generated by
+ * generate_gr_rational_resampler_base_XXX.py Any changes made to this
+ * file will be overwritten.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (int interpolation, int decimation, const std::vector<@TAP_TYPE@> &taps);
+
+class @NAME@ : public gr_block
+{
+ private:
+ @NAME@ (int interpolation, int decimation, const std::vector<@TAP_TYPE@> &taps);
+
+ public:
+ ~@NAME@ ();
+
+ void set_taps (const std::vector<@TAP_TYPE@> &taps);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_rotator.h b/gnuradio-core/src/lib/filter/gr_rotator.h
new file mode 100644
index 0000000000..930b1cc24d
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_rotator.h
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GR_ROTATOR_H_
+#define _GR_ROTATOR_H_
+
+#include <gr_complex.h>
+
+class gr_rotator {
+ gr_complex d_phase;
+ gr_complex d_phase_incr;
+
+ public:
+ gr_rotator () : d_phase (1), d_phase_incr (0) { }
+
+ void set_phase (gr_complex phase) { d_phase = phase; }
+ void set_phase_incr (gr_complex incr) { d_phase_incr = incr; }
+
+ gr_complex rotate (gr_complex in){
+ d_phase *= d_phase_incr; // incr our phase (complex mult == add phases)
+
+ d_phase /= abs(d_phase); // ensure multiplication is rotation
+ // FIXME. This is expensive. Maybe workaround using
+ // double precision complex???
+
+ return in * d_phase; // rotate in by phase
+ }
+
+};
+
+#endif /* _GR_ROTATOR_H_ */
diff --git a/gnuradio-core/src/lib/filter/gr_sincos.c b/gnuradio-core/src/lib/filter/gr_sincos.c
new file mode 100644
index 0000000000..44c85740c3
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_sincos.c
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define _GNU_SOURCE // ask for GNU extensions if available
+
+#include <gr_sincos.h>
+#include <math.h>
+
+// ----------------------------------------------------------------
+
+#if defined (HAVE_SINCOS)
+
+void
+gr_sincos (double x, double *sinx, double *cosx)
+{
+ sincos (x, sinx, cosx);
+}
+
+#else
+
+void
+gr_sincos (double x, double *sinx, double *cosx)
+{
+ *sinx = sin (x);
+ *cosx = cos (x);
+}
+
+#endif
+
+// ----------------------------------------------------------------
+
+#if defined (HAVE_SINCOSF)
+
+void
+gr_sincosf (float x, float *sinx, float *cosx)
+{
+ sincosf (x, sinx, cosx);
+}
+
+#elif defined (HAVE_SINF) && defined (HAVE_COSF)
+
+void
+gr_sincosf (float x, float *sinx, float *cosx)
+{
+ *sinx = sinf (x);
+ *cosx = cosf (x);
+}
+
+#else
+
+void
+gr_sincosf (float x, float *sinx, float *cosx)
+{
+ *sinx = sin (x);
+ *cosx = cos (x);
+}
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_sincos.h b/gnuradio-core/src/lib/filter/gr_sincos.h
new file mode 100644
index 0000000000..2e8f3ff7ac
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_sincos.h
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_SINCOS_H
+#define INCLUDED_GR_SINCOS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// compute sine and cosine at the same time
+
+void gr_sincos (double x, double *sin, double *cos);
+void gr_sincosf (float x, float *sin, float *cos);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* INCLUDED_GR_SINCOS_H */
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_avg.h b/gnuradio-core/src/lib/filter/gr_single_pole_avg.h
new file mode 100644
index 0000000000..adf871ae49
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_pole_avg.h
@@ -0,0 +1,110 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _GR_SINGLE_POLE_AVG_H_
+#define _GR_SINGLE_POLE_AVG_H_
+
+#include <stdexcept>
+
+/*!
+ * \brief class template for single pole moving average filter
+ */
+template<class o_type, class i_type, class tap_type>
+class gr_single_pole_avg {
+public:
+ /*!
+ * \brief construct new single pole moving average filter with given alpha
+ *
+ * computes y(i) = alpha * x(i) - (1-alpha) * y(i-1)
+ */
+ gr_single_pole_avg (tap_type alpha = 1.0)
+ {
+ d_prev_input = 0;
+ set_taps (alpha);
+ }
+
+ /*!
+ * \brief compute a single output value.
+ * \returns the filtered input value.
+ */
+ o_type filter (const i_type input);
+
+ /*!
+ * \brief compute an array of N output values.
+ * \p input must have n valid entries.
+ */
+ void filterN (o_type output[], const i_type input[], unsigned long n);
+
+ /*!
+ * \brief install \p alpha as the current taps.
+ */
+ void set_taps (tap_type alpha)
+ {
+ if (alpha < 0 || alpha > 1)
+ throw std::out_of_range ("Alpha must be in [0, 1]\n");
+
+ d_alpha = alpha;
+ d_one_minus_alpha = 1.0 - alpha;
+ }
+
+ //! reset state to zero
+ void reset ()
+ {
+ d_prev_input = 0;
+ }
+
+ tap_type prev_input () { return d_prev_input; }
+
+protected:
+ tap_type d_alpha;
+ tap_type d_one_minus_alpha;
+ tap_type d_prev_input;
+};
+
+
+//
+// general case. We may want to specialize this
+//
+template<class o_type, class i_type, class tap_type>
+o_type
+gr_single_pole_avg<o_type, i_type, tap_type>::filter (const i_type input)
+{
+ tap_type output;
+
+ output = d_alpha * input - d_one_minus_alpha * d_prev_input;
+ d_prev_input = input;
+
+ return (o_type) output;
+}
+
+
+template<class o_type, class i_type, class tap_type>
+void
+gr_single_pole_avg<o_type, i_type, tap_type>::filterN (o_type output[],
+ const i_type input[],
+ unsigned long n)
+{
+ for (unsigned i = 0; i < n; i++)
+ output[i] = filter (input[i]);
+}
+
+
+#endif /* _GR_SINGLE_POLE_AVG_H_ */
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_avg_filter_ff.cc b/gnuradio-core/src/lib/filter/gr_single_pole_avg_filter_ff.cc
new file mode 100644
index 0000000000..99f8b1103e
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_pole_avg_filter_ff.cc
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_single_pole_avg_filter_ff.h>
+#include <gr_io_signature.h>
+#include <stdio.h>
+
+
+gr_single_pole_avg_filter_ff_sptr
+gr_make_single_pole_avg_filter_ff (double alpha, unsigned int vlen)
+{
+ return gr_single_pole_avg_filter_ff_sptr(new gr_single_pole_avg_filter_ff(alpha, vlen));
+}
+
+gr_single_pole_avg_filter_ff::gr_single_pole_avg_filter_ff (
+ double alpha, unsigned int vlen)
+ : gr_sync_block ("single_pole_avg_filter_ff",
+ gr_make_io_signature (1, 1, sizeof (float) * vlen),
+ gr_make_io_signature (1, 1, sizeof (float) * vlen)),
+ d_vlen(vlen), d_rec(vlen)
+{
+ set_taps(alpha);
+}
+
+gr_single_pole_avg_filter_ff::~gr_single_pole_avg_filter_ff ()
+{
+ // nop
+}
+
+void
+gr_single_pole_avg_filter_ff::set_taps (double alpha)
+{
+ for (unsigned int i = 0; i < d_vlen; i++)
+ d_rec[i].set_taps(alpha);
+}
+
+int
+gr_single_pole_avg_filter_ff::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+ float *out = (float *) output_items[0];
+ unsigned int vlen = d_vlen;
+
+ if (d_vlen == 1){
+ for (int i = 0; i < noutput_items; i++)
+ out[i] = d_rec[0].filter (in[i]);
+ }
+ else {
+ for (int i = 0; i < noutput_items; i++){
+ for (unsigned int j = 0; j < vlen; j++){
+ *out++ = d_rec[j].filter (*in++);
+ }
+ }
+ }
+ return noutput_items;
+};
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_avg_filter_ff.h b/gnuradio-core/src/lib/filter/gr_single_pole_avg_filter_ff.h
new file mode 100644
index 0000000000..cc3640f689
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_pole_avg_filter_ff.h
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_SINGLE_POLE_REC_FILTER_FF_H
+#define INCLUDED_GR_SINGLE_POLE_REC_FILTER_FF_H
+
+#include <gr_sync_block.h>
+#include <gr_single_pole_avg.h>
+#include <stdexcept>
+
+class gr_single_pole_avg_filter_ff;
+typedef boost::shared_ptr<gr_single_pole_avg_filter_ff> gr_single_pole_avg_filter_ff_sptr;
+
+gr_single_pole_avg_filter_ff_sptr
+gr_make_single_pole_avg_filter_ff (double alpha, unsigned int vlen=1);
+
+/*!
+ * \brief single pole moving average filter with float input, float output
+ * \ingroup filter
+ *
+ * The input and output satisfy a difference equation of the form
+
+ \f[
+ y[n] - (1-alpha) y[n-1] = alpha x[n]
+ \f]
+
+ * with the corresponding rational system function
+
+ \f[
+ H(z) = \frac{alpha}{1 - (1-alpha) z^{-1}}
+ \f]
+
+ * Note that some texts define the system function with a + in the denominator.
+ * If you're using that convention, you'll need to negate the feedback tap.
+ */
+class gr_single_pole_avg_filter_ff : public gr_sync_block
+{
+ private:
+ friend gr_single_pole_avg_filter_ff_sptr
+ gr_make_single_pole_avg_filter_ff (double alpha, unsigned int vlen);
+
+ unsigned int d_vlen;
+ std::vector<gr_single_pole_avg<float,float,double> > d_rec;
+
+ gr_single_pole_avg_filter_ff (double alpha, unsigned int vlen);
+
+ public:
+ ~gr_single_pole_avg_filter_ff ();
+
+ void set_taps (double alpha);
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_avg_filter_ff.i b/gnuradio-core/src/lib/filter/gr_single_pole_avg_filter_ff.i
new file mode 100644
index 0000000000..f0ffe6cef9
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_pole_avg_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,single_pole_avg_filter_ff);
+
+gr_single_pole_avg_filter_ff_sptr
+gr_make_single_pole_avg_filter_ff (double alpha, unsigned int vlen=1);
+
+class gr_single_pole_avg_filter_ff : public gr_sync_block
+{
+ public:
+ ~gr_single_pole_avg_filter_ff ();
+
+ void set_taps (double alpha);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_iir.h b/gnuradio-core/src/lib/filter/gr_single_pole_iir.h
new file mode 100644
index 0000000000..c1d3f748da
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_pole_iir.h
@@ -0,0 +1,190 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _GR_SINGLE_POLE_IIR_H_
+#define _GR_SINGLE_POLE_IIR_H_
+
+#include <stdexcept>
+#include <gr_complex.h>
+/*!
+ * \brief class template for single pole IIR filter
+ */
+template<class o_type, class i_type, class tap_type>
+class gr_single_pole_iir {
+public:
+ /*!
+ * \brief construct new single pole IIR with given alpha
+ *
+ * computes y(i) = (1-alpha) * y(i-1) + alpha * x(i)
+ */
+ gr_single_pole_iir (tap_type alpha = 1.0)
+ {
+ d_prev_output = 0;
+ set_taps (alpha);
+ }
+
+ /*!
+ * \brief compute a single output value.
+ * \returns the filtered input value.
+ */
+ o_type filter (const i_type input);
+
+ /*!
+ * \brief compute an array of N output values.
+ * \p input must have n valid entries.
+ */
+ void filterN (o_type output[], const i_type input[], unsigned long n);
+
+ /*!
+ * \brief install \p alpha as the current taps.
+ */
+ void set_taps (tap_type alpha)
+ {
+ if (alpha < 0 || alpha > 1)
+ throw std::out_of_range ("Alpha must be in [0, 1]\n");
+
+ d_alpha = alpha;
+ d_one_minus_alpha = 1.0 - alpha;
+ }
+
+ //! reset state to zero
+ void reset ()
+ {
+ d_prev_output = 0;
+ }
+
+ tap_type prev_output () { return d_prev_output; }
+
+protected:
+ tap_type d_alpha;
+ tap_type d_one_minus_alpha;
+ tap_type d_prev_output;
+};
+
+
+//
+// general case. We may want to specialize this
+//
+template<class o_type, class i_type, class tap_type>
+o_type
+gr_single_pole_iir<o_type, i_type, tap_type>::filter (const i_type input)
+{
+ tap_type output;
+
+ output = d_alpha * input + d_one_minus_alpha * d_prev_output;
+ d_prev_output = output;
+
+ return (o_type) output;
+}
+
+
+template<class o_type, class i_type, class tap_type>
+void
+gr_single_pole_iir<o_type, i_type, tap_type>::filterN (o_type output[],
+ const i_type input[],
+ unsigned long n)
+{
+ for (unsigned i = 0; i < n; i++)
+ output[i] = filter (input[i]);
+}
+
+
+//
+// Specialized case for gr_complex output and double taps
+// We need to have a gr_complexd type for the calculations and prev_output variable (in stead of double)
+
+template<class i_type>
+class gr_single_pole_iir<gr_complex, i_type, double> {
+public:
+ /*!
+ * \brief construct new single pole IIR with given alpha
+ *
+ * computes y(i) = (1-alpha) * y(i-1) + alpha * x(i)
+ */
+ gr_single_pole_iir (double alpha = 1.0)
+ {
+ d_prev_output = 0;
+ set_taps (alpha);
+ }
+
+ /*!
+ * \brief compute a single output value.
+ * \returns the filtered input value.
+ */
+ gr_complex filter (const i_type input);
+
+ /*!
+ * \brief compute an array of N output values.
+ * \p input must have n valid entries.
+ */
+ void filterN (gr_complex output[], const i_type input[], unsigned long n);
+
+ /*!
+ * \brief install \p alpha as the current taps.
+ */
+ void set_taps (double alpha)
+ {
+ if (alpha < 0 || alpha > 1)
+ throw std::out_of_range ("Alpha must be in [0, 1]\n");
+
+ d_alpha = alpha;
+ d_one_minus_alpha = 1.0 - alpha;
+ }
+
+ //! reset state to zero
+ void reset ()
+ {
+ d_prev_output = 0;
+ }
+
+ gr_complexd prev_output () { return d_prev_output; }
+
+protected:
+ double d_alpha;
+ double d_one_minus_alpha;
+ gr_complexd d_prev_output;
+};
+
+template< class i_type>
+gr_complex
+gr_single_pole_iir<gr_complex, i_type, double>::filter (const i_type input)
+{
+ gr_complexd output;
+
+ output = d_alpha * (gr_complexd)input + d_one_minus_alpha * d_prev_output;
+ d_prev_output = output;
+
+ return (gr_complex) output;
+}
+
+//Do we need to specialize this, although it is the same as the general case?
+
+template<class i_type>
+void
+gr_single_pole_iir<gr_complex, i_type, double>::filterN (gr_complex output[],
+ const i_type input[],
+ unsigned long n)
+{
+ for (unsigned i = 0; i < n; i++)
+ output[i] = filter (input[i]);
+}
+
+#endif /* _GR_SINGLE_POLE_IIR_H_ */
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_cc.cc b/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_cc.cc
new file mode 100644
index 0000000000..0218452ca6
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_cc.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_single_pole_iir_filter_cc.h>
+#include <gr_io_signature.h>
+#include <stdio.h>
+
+
+gr_single_pole_iir_filter_cc_sptr
+gr_make_single_pole_iir_filter_cc (double alpha, unsigned int vlen)
+{
+ return gr_single_pole_iir_filter_cc_sptr(new gr_single_pole_iir_filter_cc(alpha, vlen));
+}
+
+gr_single_pole_iir_filter_cc::gr_single_pole_iir_filter_cc (
+ double alpha, unsigned int vlen)
+ : gr_sync_block ("single_pole_iir_filter_cc",
+ gr_make_io_signature (1, 1, sizeof (gr_complex) * vlen),
+ gr_make_io_signature (1, 1, sizeof (gr_complex) * vlen)),
+ d_vlen(vlen), d_iir(vlen)
+{
+ set_taps(alpha);
+}
+
+gr_single_pole_iir_filter_cc::~gr_single_pole_iir_filter_cc ()
+{
+ // nop
+}
+
+void
+gr_single_pole_iir_filter_cc::set_taps (double alpha)
+{
+ for (unsigned int i = 0; i < d_vlen; i++)
+ d_iir[i].set_taps(alpha);
+}
+
+int
+gr_single_pole_iir_filter_cc::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *in = (const gr_complex *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+ unsigned int vlen = d_vlen;
+
+ if (d_vlen == 1){
+ for (int i = 0; i < noutput_items; i++)
+ out[i] = d_iir[0].filter (in[i]);
+ }
+ else {
+ for (int i = 0; i < noutput_items; i++){
+ for (unsigned int j = 0; j < vlen; j++){
+ *out++ = d_iir[j].filter (*in++);
+ }
+ }
+ }
+ return noutput_items;
+};
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_cc.h b/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_cc.h
new file mode 100644
index 0000000000..38caa614bb
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_cc.h
@@ -0,0 +1,77 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_SINGLE_POLE_IIR_FILTER_CC_H
+#define INCLUDED_GR_SINGLE_POLE_IIR_FILTER_CC_H
+
+#include <gr_sync_block.h>
+#include <gr_single_pole_iir.h>
+#include <gr_complex.h>
+#include <stdexcept>
+
+class gr_single_pole_iir_filter_cc;
+typedef boost::shared_ptr<gr_single_pole_iir_filter_cc> gr_single_pole_iir_filter_cc_sptr;
+
+gr_single_pole_iir_filter_cc_sptr
+gr_make_single_pole_iir_filter_cc (double alpha, unsigned int vlen=1);
+
+/*!
+ * \brief single pole IIR filter with complex input, complex output
+ * \ingroup filter
+ *
+ * The input and output satisfy a difference equation of the form
+
+ \f[
+ y[n] - (1-alpha) y[n-1] = alpha x[n]
+ \f]
+
+ * with the corresponding rational system function
+
+ \f[
+ H(z) = \frac{alpha}{1 - (1-alpha) z^{-1}}
+ \f]
+
+ * Note that some texts define the system function with a + in the denominator.
+ * If you're using that convention, you'll need to negate the feedback tap.
+ */
+class gr_single_pole_iir_filter_cc : public gr_sync_block
+{
+ private:
+ friend gr_single_pole_iir_filter_cc_sptr
+ gr_make_single_pole_iir_filter_cc (double alpha, unsigned int vlen);
+
+ unsigned int d_vlen;
+ std::vector<gr_single_pole_iir<gr_complex,gr_complex,double> > d_iir;
+
+ gr_single_pole_iir_filter_cc (double alpha, unsigned int vlen);
+
+ public:
+ ~gr_single_pole_iir_filter_cc ();
+
+ void set_taps (double alpha);
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_cc.i b/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_cc.i
new file mode 100644
index 0000000000..683bbe99df
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,single_pole_iir_filter_cc);
+
+gr_single_pole_iir_filter_cc_sptr
+gr_make_single_pole_iir_filter_cc (double alpha, unsigned int vlen=1);
+
+class gr_single_pole_iir_filter_cc : public gr_sync_block
+{
+ public:
+ ~gr_single_pole_iir_filter_cc ();
+
+ void set_taps (double alpha);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_ff.cc b/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_ff.cc
new file mode 100644
index 0000000000..03e27484f3
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_ff.cc
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_single_pole_iir_filter_ff.h>
+#include <gr_io_signature.h>
+#include <stdio.h>
+
+
+gr_single_pole_iir_filter_ff_sptr
+gr_make_single_pole_iir_filter_ff (double alpha, unsigned int vlen)
+{
+ return gr_single_pole_iir_filter_ff_sptr(new gr_single_pole_iir_filter_ff(alpha, vlen));
+}
+
+gr_single_pole_iir_filter_ff::gr_single_pole_iir_filter_ff (
+ double alpha, unsigned int vlen)
+ : gr_sync_block ("single_pole_iir_filter_ff",
+ gr_make_io_signature (1, 1, sizeof (float) * vlen),
+ gr_make_io_signature (1, 1, sizeof (float) * vlen)),
+ d_vlen(vlen), d_iir(vlen)
+{
+ set_taps(alpha);
+}
+
+gr_single_pole_iir_filter_ff::~gr_single_pole_iir_filter_ff ()
+{
+ // nop
+}
+
+void
+gr_single_pole_iir_filter_ff::set_taps (double alpha)
+{
+ for (unsigned int i = 0; i < d_vlen; i++)
+ d_iir[i].set_taps(alpha);
+}
+
+int
+gr_single_pole_iir_filter_ff::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+ float *out = (float *) output_items[0];
+ unsigned int vlen = d_vlen;
+
+ if (d_vlen == 1){
+ for (int i = 0; i < noutput_items; i++)
+ out[i] = d_iir[0].filter (in[i]);
+ }
+ else {
+ for (int i = 0; i < noutput_items; i++){
+ for (unsigned int j = 0; j < vlen; j++){
+ *out++ = d_iir[j].filter (*in++);
+ }
+ }
+ }
+ return noutput_items;
+};
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_ff.h b/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_ff.h
new file mode 100644
index 0000000000..ff6bae3bfa
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_ff.h
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_SINGLE_POLE_IIR_FILTER_FF_H
+#define INCLUDED_GR_SINGLE_POLE_IIR_FILTER_FF_H
+
+#include <gr_sync_block.h>
+#include <gr_single_pole_iir.h>
+#include <stdexcept>
+
+class gr_single_pole_iir_filter_ff;
+typedef boost::shared_ptr<gr_single_pole_iir_filter_ff> gr_single_pole_iir_filter_ff_sptr;
+
+gr_single_pole_iir_filter_ff_sptr
+gr_make_single_pole_iir_filter_ff (double alpha, unsigned int vlen=1);
+
+/*!
+ * \brief single pole IIR filter with float input, float output
+ * \ingroup filter
+ *
+ * The input and output satisfy a difference equation of the form
+
+ \f[
+ y[n] - (1-alpha) y[n-1] = alpha x[n]
+ \f]
+
+ * with the corresponding rational system function
+
+ \f[
+ H(z) = \frac{alpha}{1 - (1-alpha) z^{-1}}
+ \f]
+
+ * Note that some texts define the system function with a + in the denominator.
+ * If you're using that convention, you'll need to negate the feedback tap.
+ */
+class gr_single_pole_iir_filter_ff : public gr_sync_block
+{
+ private:
+ friend gr_single_pole_iir_filter_ff_sptr
+ gr_make_single_pole_iir_filter_ff (double alpha, unsigned int vlen);
+
+ unsigned int d_vlen;
+ std::vector<gr_single_pole_iir<float,float,double> > d_iir;
+
+ gr_single_pole_iir_filter_ff (double alpha, unsigned int vlen);
+
+ public:
+ ~gr_single_pole_iir_filter_ff ();
+
+ void set_taps (double alpha);
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_ff.i b/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_ff.i
new file mode 100644
index 0000000000..6680c84ee3
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,single_pole_iir_filter_ff);
+
+gr_single_pole_iir_filter_ff_sptr
+gr_make_single_pole_iir_filter_ff (double alpha, unsigned int vlen=1);
+
+class gr_single_pole_iir_filter_ff : public gr_sync_block
+{
+ public:
+ ~gr_single_pole_iir_filter_ff ();
+
+ void set_taps (double alpha);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_rec.h b/gnuradio-core/src/lib/filter/gr_single_pole_rec.h
new file mode 100644
index 0000000000..f443678dc2
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_pole_rec.h
@@ -0,0 +1,110 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _GR_SINGLE_POLE_REC_H_
+#define _GR_SINGLE_POLE_REC_H_
+
+#include <stdexcept>
+
+/*!
+ * \brief class template for single pole recursive filter
+ */
+template<class o_type, class i_type, class tap_type>
+class gr_single_pole_rec {
+public:
+ /*!
+ * \brief construct new single pole IIR with given alpha
+ *
+ * computes y(i) = alpha * x(i) - (1-alpha) * y(i-1)
+ */
+ gr_single_pole_rec (tap_type alpha = 1.0)
+ {
+ d_prev_output = 0;
+ set_taps (alpha);
+ }
+
+ /*!
+ * \brief compute a single output value.
+ * \returns the filtered input value.
+ */
+ o_type filter (const i_type input);
+
+ /*!
+ * \brief compute an array of N output values.
+ * \p input must have n valid entries.
+ */
+ void filterN (o_type output[], const i_type input[], unsigned long n);
+
+ /*!
+ * \brief install \p alpha as the current taps.
+ */
+ void set_taps (tap_type alpha)
+ {
+ if (alpha < 0 || alpha > 1)
+ throw std::out_of_range ("Alpha must be in [0, 1]\n");
+
+ d_alpha = alpha;
+ d_one_minus_alpha = 1.0 - alpha;
+ }
+
+ //! reset state to pole
+ void reset ()
+ {
+ d_prev_output = 0;
+ }
+
+ tap_type prev_output () { return d_prev_output; }
+
+protected:
+ tap_type d_alpha;
+ tap_type d_one_minus_alpha;
+ tap_type d_prev_output;
+};
+
+
+//
+// general case. We may want to specialize this
+//
+template<class o_type, class i_type, class tap_type>
+o_type
+gr_single_pole_rec<o_type, i_type, tap_type>::filter (const i_type input)
+{
+ tap_type output;
+
+ output = d_alpha * input + d_one_minus_alpha * d_prev_output;
+ d_prev_output = output;
+
+ return (o_type) output;
+}
+
+
+template<class o_type, class i_type, class tap_type>
+void
+gr_single_pole_rec<o_type, i_type, tap_type>::filterN (o_type output[],
+ const i_type input[],
+ unsigned long n)
+{
+ for (unsigned i = 0; i < n; i++)
+ output[i] = filter (input[i]);
+}
+
+
+#endif /* _GR_SINGLE_POLE_REC_H_ */
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_rec_filter_ff.cc b/gnuradio-core/src/lib/filter/gr_single_pole_rec_filter_ff.cc
new file mode 100644
index 0000000000..7c0a9aa95b
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_pole_rec_filter_ff.cc
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_single_pole_rec_filter_ff.h>
+#include <gr_io_signature.h>
+#include <stdio.h>
+
+
+gr_single_pole_rec_filter_ff_sptr
+gr_make_single_pole_rec_filter_ff (double alpha, unsigned int vlen)
+{
+ return gr_single_pole_rec_filter_ff_sptr(new gr_single_pole_rec_filter_ff(alpha, vlen));
+}
+
+gr_single_pole_rec_filter_ff::gr_single_pole_rec_filter_ff (
+ double alpha, unsigned int vlen)
+ : gr_sync_block ("single_pole_rec_filter_ff",
+ gr_make_io_signature (1, 1, sizeof (float) * vlen),
+ gr_make_io_signature (1, 1, sizeof (float) * vlen)),
+ d_vlen(vlen), d_rec(vlen)
+{
+ set_taps(alpha);
+}
+
+gr_single_pole_rec_filter_ff::~gr_single_pole_rec_filter_ff ()
+{
+ // nop
+}
+
+void
+gr_single_pole_rec_filter_ff::set_taps (double alpha)
+{
+ for (unsigned int i = 0; i < d_vlen; i++)
+ d_rec[i].set_taps(alpha);
+}
+
+int
+gr_single_pole_rec_filter_ff::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+ float *out = (float *) output_items[0];
+ unsigned int vlen = d_vlen;
+
+ if (d_vlen == 1){
+ for (int i = 0; i < noutput_items; i++)
+ out[i] = d_rec[0].filter (in[i]);
+ }
+ else {
+ for (int i = 0; i < noutput_items; i++){
+ for (unsigned int j = 0; j < vlen; j++){
+ *out++ = d_rec[j].filter (*in++);
+ }
+ }
+ }
+ return noutput_items;
+};
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_rec_filter_ff.h b/gnuradio-core/src/lib/filter/gr_single_pole_rec_filter_ff.h
new file mode 100644
index 0000000000..d1861e759b
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_pole_rec_filter_ff.h
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_SINGLE_POLE_REC_FILTER_FF_H
+#define INCLUDED_GR_SINGLE_POLE_REC_FILTER_FF_H
+
+#include <gr_sync_block.h>
+#include <gr_single_pole_rec.h>
+#include <stdexcept>
+
+class gr_single_pole_rec_filter_ff;
+typedef boost::shared_ptr<gr_single_pole_rec_filter_ff> gr_single_pole_rec_filter_ff_sptr;
+
+gr_single_pole_rec_filter_ff_sptr
+gr_make_single_pole_rec_filter_ff (double alpha, unsigned int vlen=1);
+
+/*!
+ * \brief single pole recursive filter with float input, float output
+ * \ingroup filter
+ *
+ * The input and output satisfy a difference equation of the form
+
+ \f[
+ y[n] - (1-alpha) y[n-1] = alpha x[n]
+ \f]
+
+ * with the corresponding rational system function
+
+ \f[
+ H(z) = \frac{alpha}{1 - (1-alpha) z^{-1}}
+ \f]
+
+ * Note that some texts define the system function with a + in the denominator.
+ * If you're using that convention, you'll need to negate the feedback tap.
+ */
+class gr_single_pole_rec_filter_ff : public gr_sync_block
+{
+ private:
+ friend gr_single_pole_rec_filter_ff_sptr
+ gr_make_single_pole_rec_filter_ff (double alpha, unsigned int vlen);
+
+ unsigned int d_vlen;
+ std::vector<gr_single_pole_rec<float,float,double> > d_rec;
+
+ gr_single_pole_rec_filter_ff (double alpha, unsigned int vlen);
+
+ public:
+ ~gr_single_pole_rec_filter_ff ();
+
+ void set_taps (double alpha);
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_rec_filter_ff.i b/gnuradio-core/src/lib/filter/gr_single_pole_rec_filter_ff.i
new file mode 100644
index 0000000000..06da737b6b
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_pole_rec_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,single_pole_rec_filter_ff);
+
+gr_single_pole_rec_filter_ff_sptr
+gr_make_single_pole_rec_filter_ff (double alpha, unsigned int vlen=1);
+
+class gr_single_pole_rec_filter_ff : public gr_sync_block
+{
+ public:
+ ~gr_single_pole_rec_filter_ff ();
+
+ void set_taps (double alpha);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_single_zero_avg.h b/gnuradio-core/src/lib/filter/gr_single_zero_avg.h
new file mode 100644
index 0000000000..def340a05d
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_zero_avg.h
@@ -0,0 +1,110 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _GR_SINGLE_ZERO_AVG_H_
+#define _GR_SINGLE_ZERO_AVG_H_
+
+#include <stdexcept>
+
+/*!
+ * \brief class template for single zero moving average filter
+ */
+template<class o_type, class i_type, class tap_type>
+class gr_single_zero_avg {
+public:
+ /*!
+ * \brief construct new single zero moving average filter with given alpha
+ *
+ * computes y(i) = alpha * x(i) + (1-alpha) * y(i-1)
+ */
+ gr_single_zero_avg (tap_type alpha = 1.0)
+ {
+ d_prev_input = 0;
+ set_taps (alpha);
+ }
+
+ /*!
+ * \brief compute a single output value.
+ * \returns the filtered input value.
+ */
+ o_type filter (const i_type input);
+
+ /*!
+ * \brief compute an array of N output values.
+ * \p input must have n valid entries.
+ */
+ void filterN (o_type output[], const i_type input[], unsigned long n);
+
+ /*!
+ * \brief install \p alpha as the current taps.
+ */
+ void set_taps (tap_type alpha)
+ {
+ if (alpha < 0 || alpha > 1)
+ throw std::out_of_range ("Alpha must be in [0, 1]\n");
+
+ d_alpha = alpha;
+ d_one_minus_alpha = 1.0 - alpha;
+ }
+
+ //! reset state to zero
+ void reset ()
+ {
+ d_prev_input = 0;
+ }
+
+ tap_type prev_input () { return d_prev_input; }
+
+protected:
+ tap_type d_alpha;
+ tap_type d_one_minus_alpha;
+ tap_type d_prev_input;
+};
+
+
+//
+// general case. We may want to specialize this
+//
+template<class o_type, class i_type, class tap_type>
+o_type
+gr_single_zero_avg<o_type, i_type, tap_type>::filter (const i_type input)
+{
+ tap_type output;
+
+ output = d_alpha * input + d_one_minus_alpha * d_prev_input;
+ d_prev_input = input;
+
+ return (o_type) output;
+}
+
+
+template<class o_type, class i_type, class tap_type>
+void
+gr_single_zero_avg<o_type, i_type, tap_type>::filterN (o_type output[],
+ const i_type input[],
+ unsigned long n)
+{
+ for (unsigned i = 0; i < n; i++)
+ output[i] = filter (input[i]);
+}
+
+
+#endif /* _GR_SINGLE_ZERO_AVG_H_ */
diff --git a/gnuradio-core/src/lib/filter/gr_single_zero_avg_filter_ff.cc b/gnuradio-core/src/lib/filter/gr_single_zero_avg_filter_ff.cc
new file mode 100644
index 0000000000..62feb4ca8e
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_zero_avg_filter_ff.cc
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_single_zero_avg_filter_ff.h>
+#include <gr_io_signature.h>
+#include <stdio.h>
+
+
+gr_single_zero_avg_filter_ff_sptr
+gr_make_single_zero_avg_filter_ff (double alpha, unsigned int vlen)
+{
+ return gr_single_zero_avg_filter_ff_sptr(new gr_single_zero_avg_filter_ff(alpha, vlen));
+}
+
+gr_single_zero_avg_filter_ff::gr_single_zero_avg_filter_ff (
+ double alpha, unsigned int vlen)
+ : gr_sync_block ("single_zero_avg_filter_ff",
+ gr_make_io_signature (1, 1, sizeof (float) * vlen),
+ gr_make_io_signature (1, 1, sizeof (float) * vlen)),
+ d_vlen(vlen), d_rec(vlen)
+{
+ set_taps(alpha);
+}
+
+gr_single_zero_avg_filter_ff::~gr_single_zero_avg_filter_ff ()
+{
+ // nop
+}
+
+void
+gr_single_zero_avg_filter_ff::set_taps (double alpha)
+{
+ for (unsigned int i = 0; i < d_vlen; i++)
+ d_rec[i].set_taps(alpha);
+}
+
+int
+gr_single_zero_avg_filter_ff::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+ float *out = (float *) output_items[0];
+ unsigned int vlen = d_vlen;
+
+ if (d_vlen == 1){
+ for (int i = 0; i < noutput_items; i++)
+ out[i] = d_rec[0].filter (in[i]);
+ }
+ else {
+ for (int i = 0; i < noutput_items; i++){
+ for (unsigned int j = 0; j < vlen; j++){
+ *out++ = d_rec[j].filter (*in++);
+ }
+ }
+ }
+ return noutput_items;
+};
diff --git a/gnuradio-core/src/lib/filter/gr_single_zero_avg_filter_ff.h b/gnuradio-core/src/lib/filter/gr_single_zero_avg_filter_ff.h
new file mode 100644
index 0000000000..4a283d3c9c
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_zero_avg_filter_ff.h
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_SINGLE_ZERO_REC_FILTER_FF_H
+#define INCLUDED_GR_SINGLE_ZERO_REC_FILTER_FF_H
+
+#include <gr_sync_block.h>
+#include <gr_single_zero_avg.h>
+#include <stdexcept>
+
+class gr_single_zero_avg_filter_ff;
+typedef boost::shared_ptr<gr_single_zero_avg_filter_ff> gr_single_zero_avg_filter_ff_sptr;
+
+gr_single_zero_avg_filter_ff_sptr
+gr_make_single_zero_avg_filter_ff (double alpha, unsigned int vlen=1);
+
+/*!
+ * \brief single zero moving average filter with float input, float output
+ * \ingroup filter
+ *
+ * The input and output satisfy a difference equation of the form
+
+ \f[
+ y[n] - (1-alpha) y[n-1] = alpha x[n]
+ \f]
+
+ * with the corresponding rational system function
+
+ \f[
+ H(z) = \frac{alpha}{1 - (1-alpha) z^{-1}}
+ \f]
+
+ * Note that some texts define the system function with a + in the denominator.
+ * If you're using that convention, you'll need to negate the feedback tap.
+ */
+class gr_single_zero_avg_filter_ff : public gr_sync_block
+{
+ private:
+ friend gr_single_zero_avg_filter_ff_sptr
+ gr_make_single_zero_avg_filter_ff (double alpha, unsigned int vlen);
+
+ unsigned int d_vlen;
+ std::vector<gr_single_zero_avg<float,float,double> > d_rec;
+
+ gr_single_zero_avg_filter_ff (double alpha, unsigned int vlen);
+
+ public:
+ ~gr_single_zero_avg_filter_ff ();
+
+ void set_taps (double alpha);
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_single_zero_avg_filter_ff.i b/gnuradio-core/src/lib/filter/gr_single_zero_avg_filter_ff.i
new file mode 100644
index 0000000000..0e6d84fa6d
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_zero_avg_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,single_zero_avg_filter_ff);
+
+gr_single_zero_avg_filter_ff_sptr
+gr_make_single_zero_avg_filter_ff (double alpha, unsigned int vlen=1);
+
+class gr_single_zero_avg_filter_ff : public gr_sync_block
+{
+ public:
+ ~gr_single_zero_avg_filter_ff ();
+
+ void set_taps (double alpha);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_single_zero_rec.h b/gnuradio-core/src/lib/filter/gr_single_zero_rec.h
new file mode 100644
index 0000000000..f91640c590
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_zero_rec.h
@@ -0,0 +1,110 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _GR_SINGLE_ZERO_REC_H_
+#define _GR_SINGLE_ZERO_REC_H_
+
+#include <stdexcept>
+
+/*!
+ * \brief class template for single zero recursive filter
+ */
+template<class o_type, class i_type, class tap_type>
+class gr_single_zero_rec {
+public:
+ /*!
+ * \brief construct new single zero IIR with given alpha
+ *
+ * computes y(i) = alpha * x(i) - (1-alpha) * y(i-1)
+ */
+ gr_single_zero_rec (tap_type alpha = 1.0)
+ {
+ d_prev_output = 0;
+ set_taps (alpha);
+ }
+
+ /*!
+ * \brief compute a single output value.
+ * \returns the filtered input value.
+ */
+ o_type filter (const i_type input);
+
+ /*!
+ * \brief compute an array of N output values.
+ * \p input must have n valid entries.
+ */
+ void filterN (o_type output[], const i_type input[], unsigned long n);
+
+ /*!
+ * \brief install \p alpha as the current taps.
+ */
+ void set_taps (tap_type alpha)
+ {
+ if (alpha < 0 || alpha > 1)
+ throw std::out_of_range ("Alpha must be in [0, 1]\n");
+
+ d_alpha = alpha;
+ d_one_minus_alpha = 1.0 - alpha;
+ }
+
+ //! reset state to zero
+ void reset ()
+ {
+ d_prev_output = 0;
+ }
+
+ tap_type prev_output () { return d_prev_output; }
+
+protected:
+ tap_type d_alpha;
+ tap_type d_one_minus_alpha;
+ tap_type d_prev_output;
+};
+
+
+//
+// general case. We may want to specialize this
+//
+template<class o_type, class i_type, class tap_type>
+o_type
+gr_single_zero_rec<o_type, i_type, tap_type>::filter (const i_type input)
+{
+ tap_type output;
+
+ output = d_alpha * input - d_one_minus_alpha * d_prev_output;
+ d_prev_output = output;
+
+ return (o_type) output;
+}
+
+
+template<class o_type, class i_type, class tap_type>
+void
+gr_single_zero_rec<o_type, i_type, tap_type>::filterN (o_type output[],
+ const i_type input[],
+ unsigned long n)
+{
+ for (unsigned i = 0; i < n; i++)
+ output[i] = filter (input[i]);
+}
+
+
+#endif /* _GR_SINGLE_ZERO_REC_H_ */
diff --git a/gnuradio-core/src/lib/filter/gr_single_zero_rec_filter_ff.cc b/gnuradio-core/src/lib/filter/gr_single_zero_rec_filter_ff.cc
new file mode 100644
index 0000000000..fe704f453c
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_zero_rec_filter_ff.cc
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_single_zero_rec_filter_ff.h>
+#include <gr_io_signature.h>
+#include <stdio.h>
+
+
+gr_single_zero_rec_filter_ff_sptr
+gr_make_single_zero_rec_filter_ff (double alpha, unsigned int vlen)
+{
+ return gr_single_zero_rec_filter_ff_sptr(new gr_single_zero_rec_filter_ff(alpha, vlen));
+}
+
+gr_single_zero_rec_filter_ff::gr_single_zero_rec_filter_ff (
+ double alpha, unsigned int vlen)
+ : gr_sync_block ("single_zero_rec_filter_ff",
+ gr_make_io_signature (1, 1, sizeof (float) * vlen),
+ gr_make_io_signature (1, 1, sizeof (float) * vlen)),
+ d_vlen(vlen), d_rec(vlen)
+{
+ set_taps(alpha);
+}
+
+gr_single_zero_rec_filter_ff::~gr_single_zero_rec_filter_ff ()
+{
+ // nop
+}
+
+void
+gr_single_zero_rec_filter_ff::set_taps (double alpha)
+{
+ for (unsigned int i = 0; i < d_vlen; i++)
+ d_rec[i].set_taps(alpha);
+}
+
+int
+gr_single_zero_rec_filter_ff::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+ float *out = (float *) output_items[0];
+ unsigned int vlen = d_vlen;
+
+ if (d_vlen == 1){
+ for (int i = 0; i < noutput_items; i++)
+ out[i] = d_rec[0].filter (in[i]);
+ }
+ else {
+ for (int i = 0; i < noutput_items; i++){
+ for (unsigned int j = 0; j < vlen; j++){
+ *out++ = d_rec[j].filter (*in++);
+ }
+ }
+ }
+ return noutput_items;
+};
diff --git a/gnuradio-core/src/lib/filter/gr_single_zero_rec_filter_ff.h b/gnuradio-core/src/lib/filter/gr_single_zero_rec_filter_ff.h
new file mode 100644
index 0000000000..98215e9024
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_zero_rec_filter_ff.h
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_SINGLE_POLE_REC_FILTER_FF_H
+#define INCLUDED_GR_SINGLE_POLE_REC_FILTER_FF_H
+
+#include <gr_sync_block.h>
+#include <gr_single_zero_rec.h>
+#include <stdexcept>
+
+class gr_single_zero_rec_filter_ff;
+typedef boost::shared_ptr<gr_single_zero_rec_filter_ff> gr_single_zero_rec_filter_ff_sptr;
+
+gr_single_zero_rec_filter_ff_sptr
+gr_make_single_zero_rec_filter_ff (double alpha, unsigned int vlen=1);
+
+/*!
+ * \brief single zero recursive filter with float input, float output
+ * \ingroup filter
+ *
+ * The input and output satisfy a difference equation of the form
+
+ \f[
+ y[n] - (1-alpha) y[n-1] = -alpha x[n]
+ \f]
+
+ * with the corresponding system function
+
+ \f[
+ H(z) = {alpha - (1-alpha) z^{-1}}
+ \f]
+
+ * Note that some texts define the system function with a + in the denominator.
+ * If you're using that convention, you'll need to negate the feedback tap.
+ */
+class gr_single_zero_rec_filter_ff : public gr_sync_block
+{
+ private:
+ friend gr_single_zero_rec_filter_ff_sptr
+ gr_make_single_zero_rec_filter_ff (double alpha, unsigned int vlen);
+
+ unsigned int d_vlen;
+ std::vector<gr_single_zero_rec<float,float,double> > d_rec;
+
+ gr_single_zero_rec_filter_ff (double alpha, unsigned int vlen);
+
+ public:
+ ~gr_single_zero_rec_filter_ff ();
+
+ void set_taps (double alpha);
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_single_zero_rec_filter_ff.i b/gnuradio-core/src/lib/filter/gr_single_zero_rec_filter_ff.i
new file mode 100644
index 0000000000..e2cbbfc94a
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_zero_rec_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,single_zero_rec_filter_ff);
+
+gr_single_zero_rec_filter_ff_sptr
+gr_make_single_zero_rec_filter_ff (double alpha, unsigned int vlen=1);
+
+class gr_single_zero_rec_filter_ff : public gr_sync_block
+{
+ public:
+ ~gr_single_zero_rec_filter_ff ();
+
+ void set_taps (double alpha);
+};
diff --git a/gnuradio-core/src/lib/filter/gri_goertzel.cc b/gnuradio-core/src/lib/filter/gri_goertzel.cc
new file mode 100644
index 0000000000..571de61679
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_goertzel.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <cmath>
+
+#include <gri_goertzel.h>
+
+gri_goertzel::gri_goertzel(int rate, int len, float freq)
+{
+ d_d1 = 0.0;
+ d_d2 = 0.0;
+
+ float w = 2.0*M_PI*freq/rate;
+ d_wr = 2.0*std::cos(w);
+ d_wi = std::sin(w);
+
+ d_len = len;
+ d_processed = 0;
+}
+
+gr_complex gri_goertzel::batch(float *in)
+{
+ d_d1 = 0.0;
+ d_d2 = 0.0;
+
+ for(int i = 0; i < d_len; i++)
+ input(in[i]);
+
+ return output();
+}
+
+void gri_goertzel::input(const float &input)
+{
+ float y = input + d_wr*d_d1 - d_d2;
+ d_d2 = d_d1;
+ d_d1 = y;
+ d_processed++;
+}
+
+gr_complex gri_goertzel::output()
+{
+ gr_complex out((0.5*d_wr*d_d1-d_d2)/d_len, (d_wi*d_d1)/d_len);
+ d_d1 = 0.0;
+ d_d2 = 0.0;
+ d_processed = 0;
+ return out;
+}
diff --git a/gnuradio-core/src/lib/filter/gri_goertzel.h b/gnuradio-core/src/lib/filter/gri_goertzel.h
new file mode 100644
index 0000000000..6baf94e98a
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_goertzel.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GRI_GOERTZEL_H
+#define INCLUDED_GRI_GOERTZEL_H
+
+#include <gr_types.h>
+
+/*!
+ * \brief implements Goertzel single-bin DFT calculation
+ */
+
+class gri_goertzel
+{
+public:
+ gri_goertzel() {}
+ gri_goertzel(int rate, int len, float freq);
+
+ // Process a input array
+ gr_complex batch(float *in);
+
+ // Process sample by sample
+ void input(const float &in);
+ gr_complex output();
+ bool ready() const { return d_processed == d_len; }
+
+private:
+ float d_d1;
+ float d_d2;
+ float d_wr;
+ float d_wi;
+ int d_len;
+ int d_processed;
+};
+
+#endif /* INCLUDED_GRI_GOERTZEL_H */
diff --git a/gnuradio-core/src/lib/filter/gri_iir.h b/gnuradio-core/src/lib/filter/gri_iir.h
new file mode 100644
index 0000000000..7de8c69a59
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_iir.h
@@ -0,0 +1,164 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GRI_IIR_H
+#define INCLUDED_GRI_IIR_H
+
+#include <vector>
+#include <stdexcept>
+
+/*!
+ * \brief base class template for Infinite Impulse Response filter (IIR)
+ */
+template<class i_type, class o_type, class tap_type>
+class gri_iir {
+public:
+ /*!
+ * \brief Construct an IIR with the given taps.
+ *
+ * This filter uses the Direct Form I implementation, where
+ * \p fftaps contains the feed-forward taps, and \p fbtaps the feedback ones.
+ *
+ * \p fftaps and \p fbtaps must have equal numbers of taps
+ *
+ * The input and output satisfy a difference equation of the form
+
+ \f[
+ y[n] - \sum_{k=1}^{N} a_k y[n-k] = \sum_{k=0}^{M} b_k x[n-k]
+ \f]
+
+ * with the corresponding rational system function
+
+ \f[
+ H(z) = \frac{\sum_{k=0}^{M} b_k z^{-k}}{1 - \sum_{k=1}^{N} a_k z^{-k}}
+ \f]
+
+ * Note that some texts define the system function with a + in the denominator.
+ * If you're using that convention, you'll need to negate the feedback taps.
+ */
+ gri_iir (const std::vector<tap_type>& fftaps,
+ const std::vector<tap_type>& fbtaps) throw (std::invalid_argument)
+ {
+ set_taps (fftaps, fbtaps);
+ }
+
+ gri_iir () : d_latest(0) { }
+
+ ~gri_iir () {}
+
+ /*!
+ * \brief compute a single output value.
+ * \returns the filtered input value.
+ */
+ o_type filter (const i_type input);
+
+ /*!
+ * \brief compute an array of N output values.
+ * \p input must have N valid entries.
+ */
+ void filter_n (o_type output[], const i_type input[], long n);
+
+ /*!
+ * \return number of taps in filter.
+ */
+ unsigned ntaps () const { return d_fftaps.size (); }
+
+ /*!
+ * \brief install new taps.
+ */
+ void set_taps (const std::vector<tap_type> &fftaps,
+ const std::vector<tap_type> &fbtaps) throw (std::invalid_argument)
+ {
+ if (fftaps.size () != fbtaps.size ())
+ throw std::invalid_argument ("gri_iir::set_taps");
+
+ d_latest = 0;
+ d_fftaps = fftaps;
+ d_fbtaps = fbtaps;
+
+ int n = fftaps.size ();
+ d_prev_input.resize (2 * n);
+ d_prev_output.resize (2 * n);
+
+ for (int i = 0; i < 2 * n; i++){
+ d_prev_input[i] = 0;
+ d_prev_output[i] = 0;
+ }
+ }
+
+protected:
+ std::vector<tap_type> d_fftaps;
+ std::vector<tap_type> d_fbtaps;
+ int d_latest;
+ std::vector<tap_type> d_prev_output;
+ std::vector<i_type> d_prev_input;
+};
+
+
+//
+// general case. We may want to specialize this
+//
+template<class i_type, class o_type, class tap_type>
+o_type
+gri_iir<i_type, o_type, tap_type>::filter (const i_type input)
+{
+ tap_type acc;
+ unsigned i = 0;
+ unsigned n = ntaps ();
+
+ if (n == 0)
+ return (o_type) 0;
+
+ int latest = d_latest;
+
+ acc = d_fftaps[0] * input;
+ for (i = 1; i < n; i ++)
+ acc += (d_fftaps[i] * d_prev_input[latest + i]
+ + d_fbtaps[i] * d_prev_output[latest + i]);
+
+ // store the values twice to avoid having to handle wrap-around in the loop
+ d_prev_output[latest] = acc;
+ d_prev_output[latest+n] = acc;
+ d_prev_input[latest] = input;
+ d_prev_input[latest+n] = input;
+
+ latest--;
+ if (latest < 0)
+ latest += n;
+
+ d_latest = latest;
+ return (o_type) acc;
+}
+
+
+template<class i_type, class o_type, class tap_type>
+void
+gri_iir<i_type, o_type, tap_type>::filter_n (o_type output[],
+ const i_type input[],
+ long n)
+{
+ for (int i = 0; i < n; i++)
+ output[i] = filter (input[i]);
+}
+
+#endif /* INCLUDED_GRI_IIR_H */
+
diff --git a/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator.cc b/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator.cc
new file mode 100644
index 0000000000..ff7eca89ce
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gri_mmse_fir_interpolator.h>
+#include <gr_fir_util.h>
+#include <gr_fir_fff.h>
+#include <assert.h>
+#include <cmath>
+#include "interpolator_taps.h"
+
+gri_mmse_fir_interpolator::gri_mmse_fir_interpolator ()
+{
+ filters.resize (NSTEPS + 1);
+
+ for (int i = 0; i < NSTEPS + 1; i++){
+ std::vector<float> t (&taps[i][0], &taps[i][NTAPS]);
+ filters[i] = gr_fir_util::create_gr_fir_fff (t);
+ }
+}
+
+gri_mmse_fir_interpolator::~gri_mmse_fir_interpolator ()
+{
+ for (int i = 0; i < NSTEPS + 1; i++)
+ delete filters[i];
+}
+
+unsigned
+gri_mmse_fir_interpolator::ntaps () const
+{
+ return NTAPS;
+}
+
+unsigned
+gri_mmse_fir_interpolator::nsteps () const
+{
+ return NSTEPS;
+}
+
+float
+gri_mmse_fir_interpolator::interpolate (const float input[], float mu) const
+{
+ int imu = (int) rint (mu * NSTEPS);
+
+ assert (imu >= 0);
+ assert (imu <= NSTEPS);
+
+ float r = filters[imu]->filter (input);
+ return r;
+}
diff --git a/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator.h b/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator.h
new file mode 100644
index 0000000000..e2fb8f79cf
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _GRI_MMSE_FIR_INTERPOLATOR_H_
+#define _GRI_MMSE_FIR_INTERPOLATOR_H_
+
+#include <vector>
+
+class gr_fir_fff;
+
+/*!
+ * \brief Compute intermediate samples between signal samples x(k*Ts)
+ *
+ * This implements a Mininum Mean Squared Error interpolator with 8 taps.
+ * It is suitable for signals where the bandwidth of interest B = 1/(4*Ts)
+ * Where Ts is the time between samples.
+ *
+ * Although mu, the fractional delay, is specified as a float, it is actually
+ * quantized. 0.0 <= mu <= 1.0. That is, mu is quantized in the interpolate
+ * method to 32nd's of a sample.
+ */
+
+class gri_mmse_fir_interpolator {
+public:
+ gri_mmse_fir_interpolator ();
+ ~gri_mmse_fir_interpolator ();
+
+ unsigned ntaps () const;
+ unsigned nsteps () const;
+
+ /*!
+ * \brief compute a single interpolated output value.
+ * \p input must have ntaps() valid entries.
+ * input[0] .. input[ntaps() - 1] are referenced to compute the output value.
+ *
+ * \p mu must be in the range [0, 1] and specifies the fractional delay.
+ *
+ * \returns the interpolated input value.
+ */
+ float interpolate (const float input[], float mu) const;
+
+protected:
+ std::vector<gr_fir_fff *> filters;
+};
+
+
+#endif /* _GRI_MMSE_FIR_INTERPOLATOR_H_ */
diff --git a/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator_cc.cc b/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator_cc.cc
new file mode 100644
index 0000000000..3f75aedcdd
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gri_mmse_fir_interpolator_cc.h>
+#include <gr_fir_util.h>
+#include <gr_fir_ccf.h>
+#include <assert.h>
+#include <cmath>
+#include "interpolator_taps.h"
+
+gri_mmse_fir_interpolator_cc::gri_mmse_fir_interpolator_cc ()
+{
+ filters.resize (NSTEPS + 1);
+
+ for (int i = 0; i < NSTEPS + 1; i++){
+ std::vector<float> t (&taps[i][0], &taps[i][NTAPS]);
+ filters[i] = gr_fir_util::create_gr_fir_ccf (t);
+ }
+}
+
+gri_mmse_fir_interpolator_cc::~gri_mmse_fir_interpolator_cc ()
+{
+ for (int i = 0; i < NSTEPS + 1; i++)
+ delete filters[i];
+}
+
+unsigned
+gri_mmse_fir_interpolator_cc::ntaps () const
+{
+ return NTAPS;
+}
+
+unsigned
+gri_mmse_fir_interpolator_cc::nsteps () const
+{
+ return NSTEPS;
+}
+
+gr_complex
+gri_mmse_fir_interpolator_cc::interpolate (const gr_complex input[], float mu)
+{
+ int imu = (int) rint (mu * NSTEPS);
+
+ assert (imu >= 0);
+ assert (imu <= NSTEPS);
+
+ gr_complex r = filters[imu]->filter (input);
+ return r;
+}
diff --git a/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator_cc.h b/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator_cc.h
new file mode 100644
index 0000000000..d0c1411770
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator_cc.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _GRI_MMSE_FIR_INTERPOLATOR_CC_H_
+#define _GRI_MMSE_FIR_INTERPOLATOR_CC_H_
+
+#include <gr_complex.h>
+#include <vector>
+
+class gr_fir_ccf;
+
+/*!
+ * \brief Compute intermediate samples between signal samples x(k*Ts)
+ *
+ * This implements a Mininum Mean Squared Error interpolator with 8 taps.
+ * It is suitable for signals where the bandwidth of interest B = 1/(4*Ts)
+ * Where Ts is the time between samples.
+ *
+ * Although mu, the fractional delay, is specified as a float, it is actually
+ * quantized. 0.0 <= mu <= 1.0. That is, mu is quantized in the interpolate
+ * method to 32nd's of a sample.
+ */
+
+class gri_mmse_fir_interpolator_cc {
+public:
+ gri_mmse_fir_interpolator_cc ();
+ ~gri_mmse_fir_interpolator_cc ();
+
+ unsigned ntaps () const;
+ unsigned nsteps () const;
+
+ /*!
+ * \brief compute a single interpolated output value.
+ * \p input must have ntaps() valid entries.
+ * input[0] .. input[ntaps() - 1] are referenced to compute the output value.
+ *
+ * \p mu must be in the range [0, 1] and specifies the fractional delay.
+ *
+ * \returns the interpolated input value.
+ */
+ gr_complex interpolate (const gr_complex input[], float mu);
+
+protected:
+ std::vector<gr_fir_ccf *> filters;
+};
+
+
+#endif /* _GRI_MMSE_FIR_INTERPOLATOR_CC_H_ */
diff --git a/gnuradio-core/src/lib/filter/interpolator_taps.h b/gnuradio-core/src/lib/filter/interpolator_taps.h
new file mode 100644
index 0000000000..76702b63fa
--- /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 0000000000..ad6f6c6e80
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/TestAssert.h>
+#include <qa_ccomplex_dotprod_x86.h>
+#include <ccomplex_dotprod_x86.h>
+#include <string.h>
+#include <iostream>
+#include <malloc16.h>
+#include <sse_debug.h>
+#include <cmath>
+#include <gr_cpu.h>
+#include <random.h>
+
+using std::cerr;
+
+/// Macro for primitive value comparisons
+#define assertcomplexEqual(expected0,expected1,actual,delta) \
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (expected0, actual[0], delta); \
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (expected1, actual[1], delta);
+
+
+#define MAX_BLKS 10
+#define FLOATS_PER_BLK 4
+
+#define ERR_DELTA (1e-6)
+
+static float
+uniform ()
+{
+ return 2.0 * ((float) random () / RANDOM_MAX - 0.5); // uniformly (-1, 1)
+}
+
+static void
+random_floats (float *buf, unsigned n)
+{
+ for (unsigned i = 0; i < n; i++)
+ buf[i] = rint (uniform () * 32767);
+}
+
+static void
+zero_floats (float *buf, unsigned n)
+{
+ for (unsigned i = 0; i < n; i++)
+ buf[i] = 0.0;
+}
+
+void
+ref_ccomplex_dotprod (const float *input,
+ const float *taps, unsigned n_2_ccomplex_blocks,
+ float *result)
+{
+ float sum0[2] = {0,0};
+ float sum1[2] = {0,0};
+
+ do {
+
+ sum0[0] += input[0] * taps[0] - input[1] * taps[1];
+ sum0[1] += input[0] * taps[1] + input[1] * taps[0];
+ sum1[0] += input[2] * taps[2] - input[3] * taps[3];
+ sum1[1] += input[2] * taps[3] + input[3] * taps[2];
+
+ input += 4;
+ taps += 4;
+
+ } while (--n_2_ccomplex_blocks != 0);
+
+
+ result[0] = sum0[0] + sum1[0];
+ result[1] = sum0[1] + sum1[1];
+}
+
+void
+qa_ccomplex_dotprod_x86::setUp ()
+{
+ taps = (float *) calloc16Align (MAX_BLKS,
+ sizeof (float) * FLOATS_PER_BLK);
+
+ input = (float *) calloc16Align (MAX_BLKS,
+ sizeof (float) * FLOATS_PER_BLK);
+
+ if (taps == 0 || input == 0)
+ abort ();
+}
+
+void
+qa_ccomplex_dotprod_x86::tearDown ()
+{
+ free16Align (taps);
+ free16Align (input);
+ taps = 0;
+ input = 0;
+}
+
+
+void
+qa_ccomplex_dotprod_x86::zb () // "zero both"
+{
+ zero_floats (taps, MAX_BLKS * FLOATS_PER_BLK);
+ zero_floats (input, MAX_BLKS * FLOATS_PER_BLK);
+}
+
+//
+// t1
+//
+
+void
+qa_ccomplex_dotprod_x86::t1_base (ccomplex_dotprod_t ccomplex_dotprod)
+{
+ float result[2];
+
+ // cerr << "Testing dump_xmm_regs\n";
+ // dump_xmm_regs ();
+
+ // test basic cases, 1 block
+
+ zb ();
+ ccomplex_dotprod (input, taps, 1, result);
+ assertcomplexEqual (0.0, 0.0, result, ERR_DELTA);
+
+ // vary each input
+
+ zb ();
+ input[0] = 1.0; taps[0] = 1.0; taps[1] = -1.0;
+ ccomplex_dotprod (input, taps, 1, result);
+ //cerr << result[0] << " " << result[1] << "\n";
+ assertcomplexEqual (1.0, -1.0, result, ERR_DELTA);
+
+ zb ();
+ input[1] = 2.0; taps[0] = 1.0; taps[1] = -1.0;
+ ccomplex_dotprod (input, taps, 1, result);
+ assertcomplexEqual (2.0, 2.0, result, ERR_DELTA);
+
+ zb ();
+ input[2] = 3.0; taps[2] = 1.0; taps[3] = -1.0;
+ ccomplex_dotprod (input, taps, 1, result);
+ assertcomplexEqual (3.0, -3.0, result, ERR_DELTA);
+
+ zb ();
+ input[3] = 4.0; taps[2] = 1.0; taps[3] = -1.0;
+ ccomplex_dotprod (input, taps, 1, result);
+ assertcomplexEqual (4.0, 4.0, result, ERR_DELTA);
+
+ // vary each tap
+
+ zb ();
+ input[0] = 1.0; taps[0] = 0.5; taps[1] = -0.5;
+ ccomplex_dotprod (input, taps, 1, result);
+ assertcomplexEqual (0.5, -0.5, result, ERR_DELTA);
+
+ zb ();
+ input[0] = 1.0; taps[0] = 2.0; taps[1] = -2.0;
+ ccomplex_dotprod (input, taps, 1, result);
+ assertcomplexEqual (2.0, -2.0, result, ERR_DELTA);
+
+ zb ();
+ input[0] = 1.0; taps[0] = 3.0; taps[1] = -3.0;
+ ccomplex_dotprod (input, taps, 1, result);
+ assertcomplexEqual (3.0, -3.0, result, ERR_DELTA);
+
+ zb ();
+ input[0] = 1.0; taps[0] = 4.0; taps[1] = -4.0;
+ ccomplex_dotprod (input, taps, 1, result);
+ assertcomplexEqual (4.0, -4.0, result, ERR_DELTA);
+}
+
+//
+// t2
+//
+void
+qa_ccomplex_dotprod_x86::t2_base (ccomplex_dotprod_t ccomplex_dotprod)
+{
+ float result[2];
+
+ zb ();
+ input[0] = 1.0; input[1] = 3.0; taps[0] = 5.0; taps[1] = -2.0;
+
+ //1*5-3*-2 =11, 1*-2+3*5=13
+
+ ccomplex_dotprod (input, taps, 1, result);
+ assertcomplexEqual (11.0, 13.0, result, ERR_DELTA);
+
+ //7*5-13*-5 =100, 7*-5+13*5=30
+
+ input[2] = 7.0; input[3] = 13.0; taps[2] = 5.0; taps[3] = -5.0;
+
+ ccomplex_dotprod (input, taps, 1, result);
+ assertcomplexEqual (111.0, 43.0, result, ERR_DELTA);
+
+ input[4] = 19; input[5] = -19; taps[4] = 23.0; taps[5] = -23.0;
+
+ //19*23--19*-23 =0, 19*-23+-19*23=-874
+
+ ccomplex_dotprod (input, taps, 2, result);
+ assertcomplexEqual (111.0, -831.0, result, ERR_DELTA);
+
+}
+
+//
+// t3
+//
+void
+qa_ccomplex_dotprod_x86::t3_base (ccomplex_dotprod_t ccomplex_dotprod)
+{
+ srandom (0); // we want reproducibility
+
+ for (unsigned int i = 0; i < 10; i++){
+ random_floats (input, MAX_BLKS * FLOATS_PER_BLK);
+ random_floats (taps, MAX_BLKS * FLOATS_PER_BLK);
+
+ // we use a sloppy error margin because on the x86 architecture,
+ // our reference implementation is using 80 bit floating point
+ // arithmetic, while the SSE version is using 32 bit float point
+ // arithmetic.
+
+ float ref[2];
+ ref_ccomplex_dotprod (input, taps, MAX_BLKS, ref);
+ float calc[2];
+ ccomplex_dotprod (input, taps, MAX_BLKS, calc);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (ref[0],
+ calc[0],
+ fabs (ref[0]) * 1e-4);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (ref[1],
+ calc[1],
+ fabs (ref[1]) * 1e-4);
+ }
+}
+
+void
+qa_ccomplex_dotprod_x86::t1_3dnowext ()
+{
+ if (!gr_cpu::has_3dnowext ()){
+ cerr << "No 3DNow!Ext support; not tested\n";
+ }
+ else
+ t1_base (ccomplex_dotprod_3dnowext);
+}
+
+void
+qa_ccomplex_dotprod_x86::t2_3dnowext ()
+{
+ if (!gr_cpu::has_3dnowext ()){
+ cerr << "No 3DNow!Ext support; not tested\n";
+ }
+ else
+ t2_base (ccomplex_dotprod_3dnowext);
+}
+
+void
+qa_ccomplex_dotprod_x86::t3_3dnowext ()
+{
+ if (!gr_cpu::has_3dnowext ()){
+ cerr << "No 3DNow!Ext support; not tested\n";
+ }
+ else
+ t3_base (ccomplex_dotprod_3dnowext);
+}
+
+void
+qa_ccomplex_dotprod_x86::t1_3dnow ()
+{
+ if (!gr_cpu::has_3dnow ()){
+ cerr << "No 3DNow! support; not tested\n";
+ }
+ else
+ t1_base (ccomplex_dotprod_3dnow);
+}
+
+void
+qa_ccomplex_dotprod_x86::t2_3dnow ()
+{
+ if (!gr_cpu::has_3dnow ()){
+ cerr << "No 3DNow! support; not tested\n";
+ }
+ else
+ t2_base (ccomplex_dotprod_3dnow);
+}
+
+void
+qa_ccomplex_dotprod_x86::t3_3dnow ()
+{
+ if (!gr_cpu::has_3dnow ()){
+ cerr << "No 3DNow! support; not tested\n";
+ }
+ else
+ t3_base (ccomplex_dotprod_3dnow);
+}
+
+void
+qa_ccomplex_dotprod_x86::t1_sse ()
+{
+ if (!gr_cpu::has_sse ()){
+ cerr << "No SSE support; not tested\n";
+ }
+ else
+ t1_base (ccomplex_dotprod_sse);
+}
+
+void
+qa_ccomplex_dotprod_x86::t2_sse ()
+{
+ if (!gr_cpu::has_sse ()){
+ cerr << "No SSE support; not tested\n";
+ }
+ else
+ t2_base (ccomplex_dotprod_sse);
+}
+
+void
+qa_ccomplex_dotprod_x86::t3_sse ()
+{
+ if (!gr_cpu::has_sse ()){
+ cerr << "No SSE support; not tested\n";
+ }
+ else
+ t3_base (ccomplex_dotprod_sse);
+}
+
diff --git a/gnuradio-core/src/lib/filter/qa_ccomplex_dotprod_x86.h b/gnuradio-core/src/lib/filter/qa_ccomplex_dotprod_x86.h
new file mode 100644
index 0000000000..f10f0060f0
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _QA_CCOMPLEX_DOTPROD_X86_H_
+#define _QA_CCOMPLEX_DOTPROD_X86_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_ccomplex_dotprod_x86 : public CppUnit::TestCase {
+ public:
+ void setUp ();
+ void tearDown ();
+
+ CPPUNIT_TEST_SUITE (qa_ccomplex_dotprod_x86);
+ CPPUNIT_TEST (t1_3dnowext);
+ CPPUNIT_TEST (t2_3dnowext);
+ CPPUNIT_TEST (t3_3dnowext);
+ CPPUNIT_TEST (t1_3dnow);
+ CPPUNIT_TEST (t2_3dnow);
+ CPPUNIT_TEST (t3_3dnow);
+ CPPUNIT_TEST (t1_sse);
+ CPPUNIT_TEST (t2_sse);
+ CPPUNIT_TEST (t3_sse);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+
+ void t1_3dnowext ();
+ void t2_3dnowext ();
+ void t3_3dnowext ();
+ void t1_3dnow ();
+ void t2_3dnow ();
+ void t3_3dnow ();
+ void t1_sse ();
+ void t2_sse ();
+ void t3_sse ();
+
+
+ typedef void (*ccomplex_dotprod_t)(const float *input,
+ const float *taps,
+ unsigned n_2_ccomplex_blocks,
+ float *result);
+
+ void t1_base (ccomplex_dotprod_t);
+ void t2_base (ccomplex_dotprod_t);
+ void t3_base (ccomplex_dotprod_t);
+
+ void zb ();
+
+ float *taps; // 16-byte aligned
+ float *input; // 16-byte aligned
+};
+
+
+#endif /* _QA_CCOMPLEX_DOTPROD_X86_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_complex_dotprod_x86.cc b/gnuradio-core/src/lib/filter/qa_complex_dotprod_x86.cc
new file mode 100644
index 0000000000..91c8e9e272
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/TestAssert.h>
+#include <qa_complex_dotprod_x86.h>
+#include <complex_dotprod_x86.h>
+#include <string.h>
+#include <iostream>
+#include <malloc16.h>
+#include <sse_debug.h>
+#include <cmath>
+#include <gr_cpu.h>
+#include <random.h>
+
+using std::cerr;
+
+/// Macro for primitive value comparisons
+#define assertcomplexEqual(expected0,expected1,actual,delta) \
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (expected0, actual[0], delta); \
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (expected1, actual[1], delta);
+
+
+#define MAX_BLKS 10
+#define FLOATS_PER_BLK 4
+#define SHORTS_PER_BLK 2
+
+#define ERR_DELTA (1e-6)
+
+static float
+uniform ()
+{
+ return 2.0 * ((float) random () / RANDOM_MAX - 0.5); // uniformly (-1, 1)
+}
+
+static void
+random_floats (float *buf, unsigned n)
+{
+ for (unsigned i = 0; i < n; i++)
+ buf[i] = rint (uniform () * 32767);
+}
+
+static void
+zero_floats (float *buf, unsigned n)
+{
+ for (unsigned i = 0; i < n; i++)
+ buf[i] = 0.0;
+}
+
+static void
+random_shorts (short *buf, unsigned n)
+{
+ for (unsigned i = 0; i < n; i++)
+ buf[i] = (short) rint (uniform () * 32767);
+}
+
+static void
+zero_shorts (short *buf, unsigned n)
+{
+ for (unsigned i = 0; i < n; i++)
+ buf[i] = 0;
+}
+
+void
+ref_complex_dotprod (const short *input,
+ const float *taps, unsigned n_2_complex_blocks,
+ float *result)
+{
+ float sum0[2] = {0,0};
+ float sum1[2] = {0,0};
+
+ do {
+
+ sum0[0] += input[0] * taps[0];
+ sum0[1] += input[0] * taps[1];
+ sum1[0] += input[1] * taps[2];
+ sum1[1] += input[1] * taps[3];
+
+ input += 2;
+ taps += 4;
+
+ } while (--n_2_complex_blocks != 0);
+
+
+ result[0] = sum0[0] + sum1[0];
+ result[1] = sum0[1] + sum1[1];
+}
+
+void
+qa_complex_dotprod_x86::setUp ()
+{
+ taps = (float *) calloc16Align (MAX_BLKS,
+ sizeof (float) * FLOATS_PER_BLK);
+
+ input = (short *) calloc16Align (MAX_BLKS,
+ sizeof (short) * SHORTS_PER_BLK);
+
+ if (taps == 0 || input == 0)
+ abort ();
+}
+
+void
+qa_complex_dotprod_x86::tearDown ()
+{
+ free16Align (taps);
+ free16Align (input);
+ taps = 0;
+ input = 0;
+}
+
+
+void
+qa_complex_dotprod_x86::zb () // "zero both"
+{
+ zero_floats (taps, MAX_BLKS * FLOATS_PER_BLK);
+ zero_shorts (input, MAX_BLKS * SHORTS_PER_BLK);
+}
+
+//
+// t1
+//
+
+void
+qa_complex_dotprod_x86::t1_base (complex_dotprod_t complex_dotprod)
+{
+ float result[2];
+
+ // cerr << "Testing dump_xmm_regs\n";
+ // dump_xmm_regs ();
+
+ // test basic cases, 1 block
+
+ zb ();
+ complex_dotprod (input, taps, 1, result);
+ assertcomplexEqual (0.0, 0.0, result, ERR_DELTA);
+
+ // vary each input
+
+ zb ();
+ input[0] = 1; taps[0] = 1.0; taps[1] = -1.0;
+ complex_dotprod (input, taps, 1, result);
+ //cerr << result[0] << " " << result[1] << "\n";
+ assertcomplexEqual (1.0, -1.0, result, ERR_DELTA);
+
+ zb ();
+ input[1] = 2; taps[2] = 1.0; taps[3] = -1.0;
+ complex_dotprod (input, taps, 1, result);
+ assertcomplexEqual (2.0, -2.0, result, ERR_DELTA);
+
+ zb ();
+ input[2] = 3; taps[4] = 1.0; taps[5] = -1.0;
+ complex_dotprod (input, taps, 2, result);
+ assertcomplexEqual (3.0, -3.0, result, ERR_DELTA);
+
+ zb ();
+ input[3] = 4; taps[6] = 1.0; taps[7] = -1.0;
+ complex_dotprod (input, taps, 2, result);
+ assertcomplexEqual (4.0, -4.0, result, ERR_DELTA);
+
+ // vary each tap
+
+ zb ();
+ input[0] = 1; taps[0] = 0.5; taps[1] = -0.5;
+ complex_dotprod (input, taps, 1, result);
+ assertcomplexEqual (0.5, -0.5, result, ERR_DELTA);
+
+ zb ();
+ input[0] = 1; taps[0] = 2.0; taps[1] = -2.0;
+ complex_dotprod (input, taps, 1, result);
+ assertcomplexEqual (2.0, -2.0, result, ERR_DELTA);
+
+ zb ();
+ input[0] = 1; taps[0] = 3.0; taps[1] = -3.0;
+ complex_dotprod (input, taps, 1, result);
+ assertcomplexEqual (3.0, -3.0, result, ERR_DELTA);
+
+ zb ();
+ input[0] = 1; taps[0] = 4.0; taps[1] = -4.0;
+ complex_dotprod (input, taps, 1, result);
+ assertcomplexEqual (4.0, -4.0, result, ERR_DELTA);
+}
+
+//
+// t2
+//
+void
+qa_complex_dotprod_x86::t2_base (complex_dotprod_t complex_dotprod)
+{
+ float result[2];
+
+ zb ();
+ input[0] = 1; taps[0] = 2.0; taps[1] = -2.0;
+ input[1] = 3; taps[2] = 5.0; taps[3] = -5.0;
+ input[2] = 7; taps[4] = 11.0; taps[5] = -11.0;
+ input[3] = 13; taps[6] = 17.0; taps[7] = -17.0;
+
+ complex_dotprod (input, taps, 2, result);
+ assertcomplexEqual (315.0, -315.0, result, ERR_DELTA);
+
+ input[4] = 19; taps[8] = 23.0; taps[9] = -23.0;
+ complex_dotprod (input, taps, 3, result);
+ assertcomplexEqual (752.0, -752.0, result, ERR_DELTA);
+
+}
+
+//
+// t3
+//
+void
+qa_complex_dotprod_x86::t3_base (complex_dotprod_t complex_dotprod)
+{
+ srandom (0); // we want reproducibility
+
+ for (unsigned int i = 0; i < 10; i++){
+ random_shorts (input, MAX_BLKS * SHORTS_PER_BLK);
+ random_floats (taps, MAX_BLKS * FLOATS_PER_BLK);
+
+ // we use a sloppy error margin because on the x86 architecture,
+ // our reference implementation is using 80 bit floating point
+ // arithmetic, while the SSE version is using 32 bit float point
+ // arithmetic.
+
+ float ref[2];
+ ref_complex_dotprod (input, taps, MAX_BLKS, ref);
+ float calc[2];
+ complex_dotprod (input, taps, MAX_BLKS, calc);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (ref[0],
+ calc[0],
+ fabs (ref[0]) * 1e-4);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (ref[1],
+ calc[1],
+ fabs (ref[1]) * 1e-4);
+ }
+}
+
+void
+qa_complex_dotprod_x86::t1_3dnowext ()
+{
+ if (!gr_cpu::has_3dnowext ()){
+ cerr << "No 3DNow!Ext support; not tested\n";
+ }
+ else
+ t1_base (complex_dotprod_3dnowext);
+}
+
+void
+qa_complex_dotprod_x86::t2_3dnowext ()
+{
+ if (!gr_cpu::has_3dnowext ()){
+ cerr << "No 3DNow!Ext support; not tested\n";
+ }
+ else
+ t2_base (complex_dotprod_3dnowext);
+}
+
+void
+qa_complex_dotprod_x86::t3_3dnowext ()
+{
+ if (!gr_cpu::has_3dnowext ()){
+ cerr << "No 3DNow!Ext support; not tested\n";
+ }
+ else
+ t3_base (complex_dotprod_3dnowext);
+}
+
+void
+qa_complex_dotprod_x86::t1_3dnow ()
+{
+ if (!gr_cpu::has_3dnow ()){
+ cerr << "No 3DNow! support; not tested\n";
+ }
+ else
+ t1_base (complex_dotprod_3dnow);
+}
+
+void
+qa_complex_dotprod_x86::t2_3dnow ()
+{
+ if (!gr_cpu::has_3dnow ()){
+ cerr << "No 3DNow! support; not tested\n";
+ }
+ else
+ t2_base (complex_dotprod_3dnow);
+}
+
+void
+qa_complex_dotprod_x86::t3_3dnow ()
+{
+ if (!gr_cpu::has_3dnow ()){
+ cerr << "No 3DNow! support; not tested\n";
+ }
+ else
+ t3_base (complex_dotprod_3dnow);
+}
+
+void
+qa_complex_dotprod_x86::t1_sse ()
+{
+ if (!gr_cpu::has_sse ()){
+ cerr << "No SSE support; not tested\n";
+ }
+ else
+ t1_base (complex_dotprod_sse);
+}
+
+void
+qa_complex_dotprod_x86::t2_sse ()
+{
+ if (!gr_cpu::has_sse ()){
+ cerr << "No SSE support; not tested\n";
+ }
+ else
+ t2_base (complex_dotprod_sse);
+}
+
+void
+qa_complex_dotprod_x86::t3_sse ()
+{
+ if (!gr_cpu::has_sse ()){
+ cerr << "No SSE support; not tested\n";
+ }
+ else
+ t3_base (complex_dotprod_sse);
+}
+
diff --git a/gnuradio-core/src/lib/filter/qa_complex_dotprod_x86.h b/gnuradio-core/src/lib/filter/qa_complex_dotprod_x86.h
new file mode 100644
index 0000000000..53509ea6d9
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _QA_COMPLEX_DOTPROD_X86_H_
+#define _QA_COMPLEX_DOTPROD_X86_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_complex_dotprod_x86 : public CppUnit::TestCase {
+ public:
+ void setUp ();
+ void tearDown ();
+
+ CPPUNIT_TEST_SUITE (qa_complex_dotprod_x86);
+ CPPUNIT_TEST (t1_3dnowext);
+ CPPUNIT_TEST (t2_3dnowext);
+ CPPUNIT_TEST (t3_3dnowext);
+ CPPUNIT_TEST (t1_3dnow);
+ CPPUNIT_TEST (t2_3dnow);
+ CPPUNIT_TEST (t3_3dnow);
+ CPPUNIT_TEST (t1_sse);
+ CPPUNIT_TEST (t2_sse);
+ CPPUNIT_TEST (t3_sse);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+
+ void t1_3dnowext ();
+ void t2_3dnowext ();
+ void t3_3dnowext ();
+ void t1_3dnow ();
+ void t2_3dnow ();
+ void t3_3dnow ();
+ void t1_sse ();
+ void t2_sse ();
+ void t3_sse ();
+
+
+ typedef void (*complex_dotprod_t)(const short *input,
+ const float *taps,
+ unsigned n_2_complex_blocks,
+ float *result);
+
+ void t1_base (complex_dotprod_t);
+ void t2_base (complex_dotprod_t);
+ void t3_base (complex_dotprod_t);
+
+ void zb ();
+
+ float *taps; // 16-byte aligned
+ short *input; // 16-byte aligned
+};
+
+
+#endif /* _QA_COMPLEX_DOTPROD_X86_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_dotprod.h b/gnuradio-core/src/lib/filter/qa_dotprod.h
new file mode 100644
index 0000000000..3fbbdc3dc2
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _QA_DOTPROD_H_
+#define _QA_DOTPROD_H_
+
+#include <cppunit/TestSuite.h>
+
+CppUnit::TestSuite *qa_dotprod_suite ();
+
+#endif // _QA_DOTPROD_H_
+
diff --git a/gnuradio-core/src/lib/filter/qa_dotprod_generic.cc b/gnuradio-core/src/lib/filter/qa_dotprod_generic.cc
new file mode 100644
index 0000000000..d0f66cc9d5
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "qa_dotprod.h"
+
+CppUnit::TestSuite *
+qa_dotprod_suite ()
+{
+ CppUnit::TestSuite *s = new CppUnit::TestSuite ("dotprod");
+
+ // empty test suite
+
+ return s;
+}
diff --git a/gnuradio-core/src/lib/filter/qa_dotprod_x86.cc b/gnuradio-core/src/lib/filter/qa_dotprod_x86.cc
new file mode 100644
index 0000000000..6aeb49324a
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "qa_dotprod.h"
+#include "qa_float_dotprod_x86.h"
+#include "qa_complex_dotprod_x86.h"
+#include "qa_ccomplex_dotprod_x86.h"
+
+CppUnit::TestSuite *
+qa_dotprod_suite ()
+{
+ CppUnit::TestSuite *s = new CppUnit::TestSuite ("dotprod");
+
+ s->addTest (qa_float_dotprod_x86::suite ());
+ s->addTest (qa_complex_dotprod_x86::suite ());
+ s->addTest (qa_ccomplex_dotprod_x86::suite ());
+
+ return s;
+}
diff --git a/gnuradio-core/src/lib/filter/qa_filter.cc b/gnuradio-core/src/lib/filter/qa_filter.cc
new file mode 100644
index 0000000000..75415a7999
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_filter.cc
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * This class gathers together all the test cases for the gr
+ * directory into a single test suite. As you create new test cases,
+ * add them here.
+ */
+
+#include <qa_filter.h>
+#include <qa_gr_fir_ccf.h>
+#include <qa_gr_fir_fff.h>
+#include <qa_gr_fir_ccc.h>
+#include <qa_gr_fir_fcc.h>
+#include <qa_gr_fir_scc.h>
+#include <qa_gr_firdes.h>
+#include <qa_dotprod.h>
+#include <qa_gri_mmse_fir_interpolator.h>
+
+CppUnit::TestSuite *
+qa_filter::suite ()
+{
+ CppUnit::TestSuite *s = new CppUnit::TestSuite ("filter");
+
+ s->addTest (qa_dotprod_suite ());
+ s->addTest (qa_gri_mmse_fir_interpolator::suite ());
+ s->addTest (qa_gr_fir_fff::suite ());
+ s->addTest (qa_gr_fir_ccc::suite ());
+ s->addTest (qa_gr_fir_fcc::suite ());
+ s->addTest (qa_gr_fir_scc::suite ());
+ s->addTest (qa_gr_fir_ccf::suite ());
+
+ return s;
+}
diff --git a/gnuradio-core/src/lib/filter/qa_filter.h b/gnuradio-core/src/lib/filter/qa_filter.h
new file mode 100644
index 0000000000..71371ae1a9
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_filter.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _QA_FILTER_H_
+#define _QA_FILTER_H_
+
+#include <cppunit/TestSuite.h>
+
+//! collect all the tests for the gr directory
+
+class qa_filter {
+ public:
+ //! return suite of tests for all of gr directory
+ static CppUnit::TestSuite *suite ();
+};
+
+
+#endif /* _QA_FILTER_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_float_dotprod_x86.cc b/gnuradio-core/src/lib/filter/qa_float_dotprod_x86.cc
new file mode 100644
index 0000000000..a16977977c
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/TestAssert.h>
+#include <qa_float_dotprod_x86.h>
+#include <float_dotprod_x86.h>
+#include <string.h>
+#include <iostream>
+#include <malloc16.h>
+#include <sse_debug.h>
+#include <cmath>
+#include <gr_cpu.h>
+#include <random.h>
+
+using std::cerr;
+
+
+#define MAX_BLKS 10
+#define FLOATS_PER_BLK 4
+
+#define ERR_DELTA (1e-6)
+
+
+static void
+random_floats (float *buf, unsigned n)
+{
+ for (unsigned i = 0; i < n; i++)
+ buf[i] = random () - RANDOM_MAX/2;
+}
+
+static void
+zero_floats (float *buf, unsigned n)
+{
+ for (unsigned i = 0; i < n; i++)
+ buf[i] = 0.0;
+}
+
+float
+ref_float_dotprod (const float *input,
+ const float *taps, unsigned n_4_float_blocks)
+{
+ float sum0 = 0;
+ float sum1 = 0;
+ float sum2 = 0;
+ float sum3 = 0;
+
+ do {
+
+ sum0 += input[0] * taps[0];
+ sum1 += input[1] * taps[1];
+ sum2 += input[2] * taps[2];
+ sum3 += input[3] * taps[3];
+
+ input += 4;
+ taps += 4;
+
+ } while (--n_4_float_blocks != 0);
+
+
+ return sum0 + sum1 + sum2 + sum3;
+}
+
+void
+qa_float_dotprod_x86::setUp ()
+{
+ taps = (float *) calloc16Align (MAX_BLKS,
+ sizeof (float) * FLOATS_PER_BLK);
+
+ input = (float *) calloc16Align (MAX_BLKS,
+ sizeof (float) * FLOATS_PER_BLK);
+
+ if (taps == 0 || input == 0)
+ abort ();
+}
+
+void
+qa_float_dotprod_x86::tearDown ()
+{
+ free16Align (taps);
+ free16Align (input);
+ taps = 0;
+ input = 0;
+}
+
+
+void
+qa_float_dotprod_x86::zb () // "zero both"
+{
+ zero_floats (taps, MAX_BLKS * FLOATS_PER_BLK);
+ zero_floats (input, MAX_BLKS * FLOATS_PER_BLK);
+}
+
+//
+// t1
+//
+
+void
+qa_float_dotprod_x86::t1_base (float_dotprod_t float_dotprod)
+{
+
+ // cerr << "Testing dump_xmm_regs\n";
+ // dump_xmm_regs ();
+
+ // test basic cases, 1 block
+
+ zb ();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (0.0, float_dotprod (input, taps, 1), ERR_DELTA);
+
+ // vary each input
+
+ zb ();
+ input[0] = 0.5; taps[0] = 1.0;
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (0.5, float_dotprod (input, taps, 1), ERR_DELTA);
+
+ zb ();
+ input[1] = 2.0; taps[1] = 1.0;
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (2.0, float_dotprod (input, taps, 1), ERR_DELTA);
+
+ zb ();
+ input[2] = 3.0; taps[2] = 1.0;
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (3.0, float_dotprod (input, taps, 1), ERR_DELTA);
+
+ zb ();
+ input[3] = 4.0; taps[3] = 1.0;
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (4.0, float_dotprod (input, taps, 1), ERR_DELTA);
+
+ // vary each tap
+
+ zb ();
+ input[0] = 1.0; taps[0] = 0.5;
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (0.5, float_dotprod (input, taps, 1), ERR_DELTA);
+
+ zb ();
+ input[0] = 1.0; taps[0] = 2.0;
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (2.0, float_dotprod (input, taps, 1), ERR_DELTA);
+
+ zb ();
+ input[0] = 1.0; taps[0] = 3.0;
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (3.0, float_dotprod (input, taps, 1), ERR_DELTA);
+
+ zb ();
+ input[0] = 1.0; taps[0] = 4.0;
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (4.0, float_dotprod (input, taps, 1), ERR_DELTA);
+}
+
+//
+// t2
+//
+void
+qa_float_dotprod_x86::t2_base (float_dotprod_t float_dotprod)
+{
+ zb ();
+ input[0] = 1.0; taps[0] = 2.0;
+ input[1] = 3.0; taps[1] = 5.0;
+ input[2] = 7.0; taps[2] = 11.0;
+ input[3] = 13.0; taps[3] = 17.0;
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (315.0, float_dotprod (input, taps, 1), ERR_DELTA);
+
+ input[4] = 19.0; taps[4] = 23.0;
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (752.0, float_dotprod (input, taps, 2), ERR_DELTA);
+
+}
+
+//
+// t3
+//
+void
+qa_float_dotprod_x86::t3_base (float_dotprod_t float_dotprod)
+{
+ srandom (0); // we want reproducibility
+
+ for (unsigned int i = 0; i < 10; i++){
+ random_floats (input, MAX_BLKS * FLOATS_PER_BLK);
+ random_floats (taps, MAX_BLKS * FLOATS_PER_BLK);
+
+ // we use a sloppy error margin because on the x86 architecture,
+ // our reference implementation is using 80 bit floating point
+ // arithmetic, while the SSE version is using 32 bit float point
+ // arithmetic.
+
+ float ref = ref_float_dotprod (input, taps, MAX_BLKS);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (ref,
+ float_dotprod (input, taps, MAX_BLKS),
+ fabs (ref) * 1e-4);
+ }
+}
+
+void
+qa_float_dotprod_x86::t1_3dnow ()
+{
+ if (!gr_cpu::has_3dnow ()){
+ cerr << "No 3DNow! support; not tested\n";
+ }
+ else
+ t1_base (float_dotprod_3dnow);
+}
+
+void
+qa_float_dotprod_x86::t2_3dnow ()
+{
+ if (!gr_cpu::has_3dnow ()){
+ cerr << "No 3DNow! support; not tested\n";
+ }
+ else
+ t2_base (float_dotprod_3dnow);
+}
+
+void
+qa_float_dotprod_x86::t3_3dnow ()
+{
+ if (!gr_cpu::has_3dnow ()){
+ cerr << "No 3DNow! support; not tested\n";
+ }
+ else
+ t3_base (float_dotprod_3dnow);
+}
+
+void
+qa_float_dotprod_x86::t1_sse ()
+{
+ if (!gr_cpu::has_sse ()){
+ cerr << "No SSE support; not tested\n";
+ }
+ else
+ t1_base (float_dotprod_sse);
+}
+
+void
+qa_float_dotprod_x86::t2_sse ()
+{
+ if (!gr_cpu::has_sse ()){
+ cerr << "No SSE support; not tested\n";
+ }
+ else
+ t2_base (float_dotprod_sse);
+}
+
+void
+qa_float_dotprod_x86::t3_sse ()
+{
+ if (!gr_cpu::has_sse ()){
+ cerr << "No SSE support; not tested\n";
+ }
+ else
+ t3_base (float_dotprod_sse);
+}
diff --git a/gnuradio-core/src/lib/filter/qa_float_dotprod_x86.h b/gnuradio-core/src/lib/filter/qa_float_dotprod_x86.h
new file mode 100644
index 0000000000..005681290f
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _QA_FLOAT_DOTPROD_X86_H_
+#define _QA_FLOAT_DOTPROD_X86_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_float_dotprod_x86 : public CppUnit::TestCase {
+ public:
+ void setUp ();
+ void tearDown ();
+
+ CPPUNIT_TEST_SUITE (qa_float_dotprod_x86);
+ CPPUNIT_TEST (t1_3dnow);
+ CPPUNIT_TEST (t2_3dnow);
+ CPPUNIT_TEST (t3_3dnow);
+ CPPUNIT_TEST (t1_sse);
+ CPPUNIT_TEST (t2_sse);
+ CPPUNIT_TEST (t3_sse);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+
+ void t1_3dnow ();
+ void t2_3dnow ();
+ void t3_3dnow ();
+ void t1_sse ();
+ void t2_sse ();
+ void t3_sse ();
+
+
+ typedef float (*float_dotprod_t)(const float *input,
+ const float *taps,
+ unsigned n_4_float_blocks);
+
+ void t1_base (float_dotprod_t);
+ void t2_base (float_dotprod_t);
+ void t3_base (float_dotprod_t);
+
+
+ void zb ();
+
+ float *taps; // 16-byte aligned
+ float *input; // 16-byte aligned
+
+};
+
+
+#endif /* _QA_FLOAT_DOTPROD_X86_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_gr_fir_ccc.cc b/gnuradio-core/src/lib/filter/qa_gr_fir_ccc.cc
new file mode 100644
index 0000000000..9c70a16775
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gr_fir_ccc.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * FIXME. This code is virtually identical to qa_gr_fir_?CC.cc
+ * Kludge up some kind of macro to handle the minor differences.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_types.h>
+
+typedef gr_complex i_type;
+typedef gr_complex o_type;
+typedef gr_complex tap_type;
+typedef gr_complex acc_type;
+
+
+#include <qa_gr_fir_ccc.h>
+#include <gr_fir_ccc.h>
+#include <gr_fir_util.h>
+#include <string.h>
+#include <iostream>
+#include <cmath>
+#include <gr_types.h>
+#include <cppunit/TestAssert.h>
+#include <random.h>
+#include <malloc16.h>
+
+using std::vector;
+
+#define ERR_DELTA (1e-5)
+
+#define NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+//
+// typedef for something logically "pointer to constructor".
+// there may be a better way, please let me know...
+//
+typedef gr_fir_ccc* (*fir_maker_t)(const std::vector<tap_type> &taps);
+
+
+static float
+uniform ()
+{
+ return 2.0 * ((float) random () / RANDOM_MAX - 0.5); // uniformly (-1, 1)
+}
+
+static void
+random_input (i_type *buf, unsigned n)
+{
+ for (unsigned i = 0; i < n; i++)
+ buf[i] = (i_type) rint (uniform () * 32767);
+}
+
+static void
+random_complex (gr_complex *buf, unsigned n)
+{
+ for (unsigned i = 0; i < n; i++){
+ float re = rint (uniform () * 32767);
+ float im = rint (uniform () * 32767);
+ buf[i] = gr_complex (re, im);
+ }
+}
+
+static o_type
+ref_dotprod (const i_type input[], const tap_type taps[], int ntaps)
+{
+ acc_type sum = 0;
+ for (int i = 0; i < ntaps; i++)
+ sum += input[i] * taps[ntaps - i - 1];
+
+ return sum;
+}
+
+//
+// Test for ntaps in [0,9], and input lengths in [0,17].
+// This ensures that we are building the shifted taps correctly,
+// and exercises all corner cases on input alignment and length.
+//
+
+static void
+test_random_io (fir_maker_t maker)
+{
+ const int MAX_TAPS = 9;
+ const int OUTPUT_LEN = 17;
+ const int INPUT_LEN = MAX_TAPS + OUTPUT_LEN;
+
+ // Our SIMD ccc kernel requires that the complex input be 64-bit (8-byte) aligned.
+ // i_type input[INPUT_LEN];
+ i_type *input = (i_type *)malloc16Align(INPUT_LEN * sizeof(i_type));
+ o_type expected_output[OUTPUT_LEN];
+ o_type actual_output[OUTPUT_LEN];
+ tap_type taps[MAX_TAPS];
+
+
+ srandom (0); // we want reproducibility
+
+ for (int n = 0; n <= MAX_TAPS; n++){
+ for (int ol = 0; ol <= OUTPUT_LEN; ol++){
+
+ // cerr << "@@@ n:ol " << n << ":" << ol << endl;
+
+ // build random test case
+ random_input (input, INPUT_LEN);
+ random_complex (taps, MAX_TAPS);
+
+ // compute expected output values
+ for (int o = 0; o < ol; o++){
+ expected_output[o] = ref_dotprod (&input[o], taps, n);
+ }
+
+ // build filter
+
+ vector<tap_type> f1_taps (&taps[0], &taps[n]);
+ gr_fir_ccc *f1 = maker (f1_taps);
+
+ // zero the output, then do the filtering
+ memset (actual_output, 0, sizeof (actual_output));
+ f1->filterN (actual_output, input, ol);
+
+ // check results
+ //
+ // we use a sloppy error margin because on the x86 architecture,
+ // our reference implementation is using 80 bit floating point
+ // arithmetic, while the SSE version is using 32 bit float point
+ // arithmetic.
+
+ for (int o = 0; o < ol; o++){
+ ASSERT_COMPLEXES_EQUAL (expected_output[o],
+ actual_output[o],
+ abs (expected_output[o]) * ERR_DELTA);
+ }
+
+ delete f1;
+ }
+ }
+ free16Align(input);
+}
+
+static void
+for_each (void (*f)(fir_maker_t))
+{
+ std::vector<gr_fir_ccc_info> info;
+ gr_fir_util::get_gr_fir_ccc_info (&info); // get all known ccc implementations
+
+ for (std::vector<gr_fir_ccc_info>::iterator p = info.begin ();
+ p != info.end ();
+ ++p){
+
+ std::cerr << " [" << p->name << "]";
+ f (p->create);
+ }
+
+ std::cerr << std::endl;
+}
+
+void
+qa_gr_fir_ccc::t1 ()
+{
+ for_each (test_random_io);
+}
diff --git a/gnuradio-core/src/lib/filter/qa_gr_fir_ccc.h b/gnuradio-core/src/lib/filter/qa_gr_fir_ccc.h
new file mode 100644
index 0000000000..46fa9b0e94
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _QA_GR_FIR_CCC_H_
+#define _QA_GR_FIR_CCC_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_fir_ccc : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gr_fir_ccc);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void t1 ();
+
+};
+
+
+#endif /* _QA_GR_FIR_CCC_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_gr_fir_ccf.cc b/gnuradio-core/src/lib/filter/qa_gr_fir_ccf.cc
new file mode 100644
index 0000000000..c45e085347
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gr_fir_ccf.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * FIXME. This code is virtually identical to qa_gr_fir_?CC.cc
+ * Kludge up some kind of macro to handle the minor differences.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_types.h>
+
+typedef gr_complex i_type;
+typedef gr_complex o_type;
+typedef float tap_type;
+typedef gr_complex acc_type;
+
+
+#include <qa_gr_fir_ccf.h>
+#include <gr_fir_ccf.h>
+#include <gr_fir_util.h>
+#include <string.h>
+#include <iostream>
+#include <cmath>
+#include <gr_types.h>
+#include <cppunit/TestAssert.h>
+#include <random.h>
+#include <malloc16.h>
+
+using std::vector;
+
+#define ERR_DELTA (1e-5)
+
+#define NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+//
+// typedef for something logically "pointer to constructor".
+// there may be a better way, please let me know...
+//
+typedef gr_fir_ccf* (*fir_maker_t)(const std::vector<tap_type> &taps);
+
+static float
+uniform ()
+{
+ return 2.0 * ((float) random () / RANDOM_MAX - 0.5); // uniformly (-1, 1)
+}
+
+static void
+random_floats (float *buf, unsigned n)
+{
+ for (unsigned i = 0; i < n; i++)
+ buf[i] = (float) rint (uniform () * 32767);
+}
+
+static void
+random_complex (gr_complex *buf, unsigned n)
+{
+ for (unsigned i = 0; i < n; i++){
+ float re = rint (uniform () * 32767);
+ float im = rint (uniform () * 32767);
+ buf[i] = gr_complex (re, im);
+ }
+}
+
+static o_type
+ref_dotprod (const i_type input[], const tap_type taps[], int ntaps)
+{
+ acc_type sum = 0;
+ for (int i = 0; i < ntaps; i++)
+ sum += input[i] * taps[ntaps - i - 1];
+
+ return sum;
+}
+
+//
+// Test for ntaps in [0,9], and input lengths in [0,17].
+// This ensures that we are building the shifted taps correctly,
+// and exercises all corner cases on input alignment and length.
+//
+
+static void
+test_random_io (fir_maker_t maker)
+{
+ const int MAX_TAPS = 9;
+ const int OUTPUT_LEN = 17;
+ const int INPUT_LEN = MAX_TAPS + OUTPUT_LEN;
+
+ // Our SIMD ccc kernel requires that the complex input be 64-bit (8-byte) aligned.
+ //i_type input[INPUT_LEN];
+ i_type *input = (i_type *)malloc16Align(INPUT_LEN * sizeof(i_type));
+ o_type expected_output[OUTPUT_LEN];
+ o_type actual_output[OUTPUT_LEN];
+ tap_type taps[MAX_TAPS];
+
+
+ srandom (0); // we want reproducibility
+
+ for (int n = 0; n <= MAX_TAPS; n++){
+ for (int ol = 0; ol <= OUTPUT_LEN; ol++){
+
+ // cerr << "@@@ n:ol " << n << ":" << ol << endl;
+
+ // build random test case
+ random_complex (input, INPUT_LEN);
+ random_floats (taps, MAX_TAPS);
+
+ // compute expected output values
+ for (int o = 0; o < ol; o++){
+ expected_output[o] = ref_dotprod (&input[o], taps, n);
+ }
+
+ // build filter
+
+ vector<tap_type> f1_taps (&taps[0], &taps[n]);
+ gr_fir_ccf *f1 = maker (f1_taps);
+
+ // zero the output, then do the filtering
+ memset (actual_output, 0, sizeof (actual_output));
+ f1->filterN (actual_output, input, ol);
+
+ // check results
+ //
+ // we use a sloppy error margin because on the x86 architecture,
+ // our reference implementation is using 80 bit floating point
+ // arithmetic, while the SSE version is using 32 bit float point
+ // arithmetic.
+
+ for (int o = 0; o < ol; o++){
+ ASSERT_COMPLEXES_EQUAL (expected_output[o], actual_output[o],
+ abs (expected_output[o]) * ERR_DELTA);
+ }
+
+ delete f1;
+ }
+ }
+ free16Align(input);
+}
+
+
+static void
+for_each (void (*f)(fir_maker_t))
+{
+ std::vector<gr_fir_ccf_info> info;
+ gr_fir_util::get_gr_fir_ccf_info (&info); // get all known ccf implementations
+
+ for (std::vector<gr_fir_ccf_info>::iterator p = info.begin ();
+ p != info.end ();
+ ++p){
+
+ std::cerr << " [" << p->name << "]";
+ f (p->create);
+ }
+
+ std::cerr << std::endl;
+}
+
+
+void
+qa_gr_fir_ccf::t1 ()
+{
+ for_each (test_random_io);
+}
diff --git a/gnuradio-core/src/lib/filter/qa_gr_fir_ccf.h b/gnuradio-core/src/lib/filter/qa_gr_fir_ccf.h
new file mode 100644
index 0000000000..bf87136d05
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _QA_GR_FIR_CCF_H_
+#define _QA_GR_FIR_CCF_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_fir_ccf : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gr_fir_ccf);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+
+ void t1 ();
+ // void t2 ();
+ // void t3 ();
+
+};
+
+
+#endif /* _QA_GR_FIR_CCF_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_gr_fir_fcc.cc b/gnuradio-core/src/lib/filter/qa_gr_fir_fcc.cc
new file mode 100644
index 0000000000..0706b585d9
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gr_fir_fcc.cc
@@ -0,0 +1,180 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * FIXME. This code is virtually identical to qa_gr_fir_?CC.cc
+ * Kludge up some kind of macro to handle the minor differences.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_types.h>
+
+typedef float i_type;
+typedef gr_complex o_type;
+typedef gr_complex tap_type;
+typedef gr_complex acc_type;
+
+
+#include <qa_gr_fir_fcc.h>
+#include <gr_fir_fcc.h>
+#include <gr_fir_util.h>
+#include <string.h>
+#include <iostream>
+#include <cmath>
+#include <gr_types.h>
+#include <cppunit/TestAssert.h>
+#include <random.h>
+
+using std::vector;
+
+#define ERR_DELTA (1e-5)
+
+#define NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+
+//
+// typedef for something logically "pointer to constructor".
+// there may be a better way, please let me know...
+//
+typedef gr_fir_fcc* (*fir_maker_t)(const std::vector<tap_type> &taps);
+
+
+static float
+uniform ()
+{
+ return 2.0 * ((float) random () / RANDOM_MAX - 0.5); // uniformly (-1, 1)
+}
+
+static void
+random_input (i_type *buf, unsigned n)
+{
+ for (unsigned i = 0; i < n; i++)
+ buf[i] = (i_type) rint (uniform () * 32767);
+}
+
+static void
+random_complex (gr_complex *buf, unsigned n)
+{
+ for (unsigned i = 0; i < n; i++){
+ float re = rint (uniform () * 32767);
+ float im = rint (uniform () * 32767);
+ buf[i] = gr_complex (re, im);
+ }
+}
+
+static o_type
+ref_dotprod (const i_type input[], const tap_type taps[], int ntaps)
+{
+ acc_type sum = 0;
+ for (int i = 0; i < ntaps; i++)
+ sum += input[i] * taps[ntaps - i - 1];
+
+ return sum;
+}
+
+//
+// Test for ntaps in [0,9], and input lengths in [0,17].
+// This ensures that we are building the shifted taps correctly,
+// and exercises all corner cases on input alignment and length.
+//
+
+static void
+test_random_io (fir_maker_t maker)
+{
+ const int MAX_TAPS = 9;
+ const int OUTPUT_LEN = 17;
+ const int INPUT_LEN = MAX_TAPS + OUTPUT_LEN;
+
+ i_type input[INPUT_LEN];
+ o_type expected_output[OUTPUT_LEN];
+ o_type actual_output[OUTPUT_LEN];
+ tap_type taps[MAX_TAPS];
+
+
+ srandom (0); // we want reproducibility
+
+ for (int n = 0; n <= MAX_TAPS; n++){
+ for (int ol = 0; ol <= OUTPUT_LEN; ol++){
+
+ // cerr << "@@@ n:ol " << n << ":" << ol << endl;
+
+ // build random test case
+ random_input (input, INPUT_LEN);
+ random_complex (taps, MAX_TAPS);
+
+ // compute expected output values
+ for (int o = 0; o < ol; o++){
+ expected_output[o] = ref_dotprod (&input[o], taps, n);
+ }
+
+ // build filter
+
+ vector<tap_type> f1_taps (&taps[0], &taps[n]);
+ gr_fir_fcc *f1 = maker (f1_taps);
+
+ // zero the output, then do the filtering
+ memset (actual_output, 0, sizeof (actual_output));
+ f1->filterN (actual_output, input, ol);
+
+ // check results
+ //
+ // we use a sloppy error margin because on the x86 architecture,
+ // our reference implementation is using 80 bit floating point
+ // arithmetic, while the SSE version is using 32 bit float point
+ // arithmetic.
+
+ for (int o = 0; o < ol; o++){
+ ASSERT_COMPLEXES_EQUAL (expected_output[o],
+ actual_output[o],
+ abs (expected_output[o]) * ERR_DELTA);
+ }
+
+ delete f1;
+ }
+ }
+}
+
+static void
+for_each (void (*f)(fir_maker_t))
+{
+ std::vector<gr_fir_fcc_info> info;
+ gr_fir_util::get_gr_fir_fcc_info (&info); // get all known fcc implementations
+
+ for (std::vector<gr_fir_fcc_info>::iterator p = info.begin ();
+ p != info.end ();
+ ++p){
+
+ std::cerr << " [" << p->name << "]";
+ f (p->create);
+ }
+
+ std::cerr << std::endl;
+}
+
+void
+qa_gr_fir_fcc::t1 ()
+{
+ for_each (test_random_io);
+}
diff --git a/gnuradio-core/src/lib/filter/qa_gr_fir_fcc.h b/gnuradio-core/src/lib/filter/qa_gr_fir_fcc.h
new file mode 100644
index 0000000000..145f72f004
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _QA_GR_FIR_FCC_H_
+#define _QA_GR_FIR_FCC_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_fir_fcc : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gr_fir_fcc);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+
+ void t1 ();
+};
+
+
+#endif /* _QA_GR_FIR_FCC_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_gr_fir_fff.cc b/gnuradio-core/src/lib/filter/qa_gr_fir_fff.cc
new file mode 100644
index 0000000000..1ba3bee551
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gr_fir_fff.cc
@@ -0,0 +1,225 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qa_gr_fir_fff.h>
+#include <gr_fir_fff.h>
+#include <gr_fir_util.h>
+#include <string.h>
+#include <iostream>
+#include <cmath>
+#include <cppunit/TestAssert.h>
+#include <random.h>
+
+using std::vector;
+
+typedef float i_type;
+typedef float o_type;
+typedef float tap_type;
+typedef float acc_type;
+
+#define ERR_DELTA (1e-6)
+
+#define NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+
+//
+// typedef for something logically "pointer to constructor".
+// there may be a better way, please let me know...
+//
+typedef gr_fir_fff* (*fir_maker_t)(const std::vector<tap_type> &taps);
+
+
+// ----------------------------------------------------------------
+
+const static i_type input_1[] = {
+ 234, -4, 23, -56, 45, 98, -23, -7
+};
+
+const static tap_type taps_1a[] = {
+ -3
+};
+
+const static o_type expected_1a[] = {
+ -702, 12, -69, 168, -135, -294, 69, 21
+};
+
+const static tap_type taps_1b[] = {
+ -4, 5
+};
+
+const static o_type expected_1b[] = {
+ 1186, -112, 339, -460, -167, 582, -87
+};
+
+// ----------------------------------------------------------------
+
+static void
+test_known_io (fir_maker_t maker)
+{
+ vector<tap_type> t1a (&taps_1a[0], &taps_1a[NELEM (taps_1a)]);
+ vector<tap_type> t1b (&taps_1b[0], &taps_1b[NELEM (taps_1b)]);
+
+ gr_fir_fff *f1 = maker (t1a); // create filter
+ CPPUNIT_ASSERT_EQUAL ((unsigned) 1, f1->ntaps ()); // check ntaps
+
+ // check filter output
+ int n = NELEM (input_1) - f1->ntaps () + 1;
+ for (int i = 0; i < n; i++)
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (expected_1a[i], f1->filter (&input_1[i]), ERR_DELTA);
+
+ f1->set_taps (t1b); // set new taps
+ CPPUNIT_ASSERT_EQUAL ((unsigned) 2, f1->ntaps ()); // check ntaps
+
+ // check filter output
+ n = NELEM (input_1) - f1->ntaps () + 1;
+ for (int i = 0; i < n; i++)
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (expected_1b[i], f1->filter (&input_1[i]), ERR_DELTA);
+
+ // test filterN interface
+
+ o_type output[NELEM (expected_1b)];
+ memset (output, 0, sizeof (output));
+
+ f1->filterN (output, input_1, n);
+ for (int i = 0; i < n; i++)
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (expected_1b[i], output[i], ERR_DELTA);
+
+ delete f1;
+}
+
+//
+// Test for ntaps in [0,9], and input lengths in [0,17].
+// This ensures that we are building the shifted taps correctly,
+// and exercises all corner cases on input alignment and length.
+//
+
+static float
+uniform ()
+{
+ return 2.0 * ((float) random () / RANDOM_MAX - 0.5); // uniformly (-1, 1)
+}
+
+static void
+random_floats (float *buf, unsigned n)
+{
+ for (unsigned i = 0; i < n; i++)
+ buf[i] = rint (uniform () * 32768);
+}
+
+static o_type
+ref_dotprod (const i_type input[], const tap_type taps[], int ntaps)
+{
+ acc_type sum = 0;
+ for (int i = 0; i < ntaps; i++)
+ sum += input[i] * taps[ntaps - i - 1];
+
+ return sum;
+}
+
+static void
+test_random_io (fir_maker_t maker)
+{
+ const int MAX_TAPS = 9;
+ const int OUTPUT_LEN = 17;
+ const int INPUT_LEN = MAX_TAPS + OUTPUT_LEN;
+
+ i_type input[INPUT_LEN];
+ o_type expected_output[OUTPUT_LEN];
+ o_type actual_output[OUTPUT_LEN];
+ tap_type taps[MAX_TAPS];
+
+
+ srandom (0); // we want reproducibility
+
+ for (int n = 0; n <= MAX_TAPS; n++){
+ for (int ol = 0; ol <= OUTPUT_LEN; ol++){
+
+ // cerr << "@@@ n:ol " << n << ":" << ol << endl;
+
+ // build random test case
+ random_floats (input, INPUT_LEN);
+ random_floats (taps, MAX_TAPS);
+
+ // compute expected output values
+ for (int o = 0; o < ol; o++){
+ expected_output[o] = ref_dotprod (&input[o], taps, n);
+ }
+
+ // build filter
+
+ vector<tap_type> f1_taps (&taps[0], &taps[n]);
+ gr_fir_fff *f1 = maker (f1_taps);
+
+ // zero the output, then do the filtering
+ memset (actual_output, 0, sizeof (actual_output));
+ f1->filterN (actual_output, input, ol);
+
+ // check results
+ //
+ // we use a sloppy error margin because on the x86 architecture,
+ // our reference implementation is using 80 bit floating point
+ // arithmetic, while the SSE version is using 32 bit float point
+ // arithmetic.
+
+ for (int o = 0; o < ol; o++){
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (expected_output[o], actual_output[o],
+ fabs (expected_output[o]) * 1e-4);
+ }
+
+ delete f1;
+ }
+ }
+}
+
+
+static void
+for_each (void (*f)(fir_maker_t))
+{
+ std::vector<gr_fir_fff_info> info;
+ gr_fir_util::get_gr_fir_fff_info (&info); // get all known fff implementations
+
+ for (std::vector<gr_fir_fff_info>::iterator p = info.begin ();
+ p != info.end ();
+ ++p){
+
+ std::cerr << " [" << p->name << "]";
+ f (p->create);
+ }
+
+ std::cerr << std::endl;
+}
+
+void
+qa_gr_fir_fff::t1 ()
+{
+ for_each (test_known_io);
+}
+
+void
+qa_gr_fir_fff::t2 ()
+{
+ for_each (test_random_io);
+}
diff --git a/gnuradio-core/src/lib/filter/qa_gr_fir_fff.h b/gnuradio-core/src/lib/filter/qa_gr_fir_fff.h
new file mode 100644
index 0000000000..34d86f9d16
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _QA_GR_FIR_FFF_H_
+#define _QA_GR_FIR_FFF_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_fir_fff : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gr_fir_fff);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+
+ void t1 ();
+ void t2 ();
+
+};
+
+
+#endif /* _QA_GR_FIR_FFF_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_gr_fir_scc.cc b/gnuradio-core/src/lib/filter/qa_gr_fir_scc.cc
new file mode 100644
index 0000000000..38a76924c6
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * FIXME. This code is virtually identical to qa_gr_fir_?CC.cc
+ * Kludge up some kind of macro to handle the minor differences.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_types.h>
+
+typedef short i_type;
+typedef gr_complex o_type;
+typedef gr_complex tap_type;
+typedef gr_complex acc_type;
+
+
+#include <qa_gr_fir_scc.h>
+#include <gr_fir_scc.h>
+#include <gr_fir_util.h>
+#include <string.h>
+#include <iostream>
+#include <cmath>
+#include <gr_types.h>
+#include <cppunit/TestAssert.h>
+#include <random.h>
+
+using std::vector;
+
+#define ERR_DELTA (1e-5)
+
+#define NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+//
+// typedef for something logically "pointer to constructor".
+// there may be a better way, please let me know...
+//
+typedef gr_fir_scc* (*fir_maker_t)(const std::vector<tap_type> &taps);
+
+
+static float
+uniform ()
+{
+ return 2.0 * ((float) random () / RANDOM_MAX - 0.5); // uniformly (-1, 1)
+}
+
+static void
+random_input (i_type *buf, unsigned n)
+{
+ for (unsigned i = 0; i < n; i++)
+ buf[i] = (i_type) rint (uniform () * 32767);
+}
+
+static void
+random_complex (gr_complex *buf, unsigned n)
+{
+ for (unsigned i = 0; i < n; i++){
+ float re = rint (uniform () * 32767);
+ float im = rint (uniform () * 32767);
+ buf[i] = gr_complex (re, im);
+ }
+}
+
+static o_type
+ref_dotprod (const i_type input[], const tap_type taps[], int ntaps)
+{
+ acc_type sum = 0;
+ for (int i = 0; i < ntaps; i++)
+ sum += (float) input[i] * taps[ntaps - i - 1];
+
+ return sum;
+}
+
+//
+// Test for ntaps in [0,9], and input lengths in [0,17].
+// This ensures that we are building the shifted taps correctly,
+// and exercises all corner cases on input alignment and length.
+//
+
+static void
+test_random_io (fir_maker_t maker)
+{
+ const int MAX_TAPS = 9;
+ const int OUTPUT_LEN = 17;
+ const int INPUT_LEN = MAX_TAPS + OUTPUT_LEN;
+
+ i_type input[INPUT_LEN];
+ o_type expected_output[OUTPUT_LEN];
+ o_type actual_output[OUTPUT_LEN];
+ tap_type taps[MAX_TAPS];
+
+
+ srandom (0); // we want reproducibility
+
+ for (int n = 0; n <= MAX_TAPS; n++){
+ for (int ol = 0; ol <= OUTPUT_LEN; ol++){
+
+ // cerr << "@@@ n:ol " << n << ":" << ol << endl;
+
+ // build random test case
+ random_input (input, INPUT_LEN);
+ random_complex (taps, MAX_TAPS);
+
+ // compute expected output values
+ for (int o = 0; o < ol; o++){
+ expected_output[o] = ref_dotprod (&input[o], taps, n);
+ }
+
+ // build filter
+
+ vector<tap_type> f1_taps (&taps[0], &taps[n]);
+ gr_fir_scc *f1 = maker (f1_taps);
+
+ // zero the output, then do the filtering
+ memset (actual_output, 0, sizeof (actual_output));
+ f1->filterN (actual_output, input, ol);
+
+ // check results
+ //
+ // we use a sloppy error margin because on the x86 architecture,
+ // our reference implementation is using 80 bit floating point
+ // arithmetic, while the SSE version is using 32 bit float point
+ // arithmetic.
+
+ for (int o = 0; o < ol; o++){
+ ASSERT_COMPLEXES_EQUAL (expected_output[o],
+ actual_output[o],
+ abs (expected_output[o]) * ERR_DELTA);
+ }
+
+ delete f1;
+ }
+ }
+}
+
+static void
+for_each (void (*f)(fir_maker_t))
+{
+ std::vector<gr_fir_scc_info> info;
+ gr_fir_util::get_gr_fir_scc_info (&info); // get all known scc implementations
+
+ for (std::vector<gr_fir_scc_info>::iterator p = info.begin ();
+ p != info.end ();
+ ++p){
+
+ std::cerr << " [" << p->name << "]";
+ f (p->create);
+ }
+
+ std::cerr << std::endl;
+}
+
+void
+qa_gr_fir_scc::t1 ()
+{
+ for_each (test_random_io);
+}
diff --git a/gnuradio-core/src/lib/filter/qa_gr_fir_scc.h b/gnuradio-core/src/lib/filter/qa_gr_fir_scc.h
new file mode 100644
index 0000000000..2662d02b44
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _QA_GR_FIR_SCC_H_
+#define _QA_GR_FIR_SCC_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_fir_scc : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gr_fir_scc);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void t1 ();
+
+};
+
+
+#endif /* _QA_GR_FIR_SCC_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator.cc b/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator.cc
new file mode 100644
index 0000000000..a756bbc4a4
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator.cc
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <cppunit/TestAssert.h>
+#include <qa_gri_mmse_fir_interpolator.h>
+#include <gri_mmse_fir_interpolator.h>
+#include <stdio.h>
+#include <cmath>
+
+#define NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+
+static float
+test_fcn (double index)
+{
+ return (2 * sin (index * 0.25 * 2 * M_PI + 0.125 * M_PI)
+ + 3 * sin (index * 0.077 * 2 * M_PI + 0.3 * M_PI));
+}
+
+
+void
+qa_gri_mmse_fir_interpolator::t1 ()
+{
+ static const unsigned N = 100;
+ float input[N + 10];
+
+ for (unsigned i = 0; i < NELEM(input); i++)
+ input[i] = test_fcn ((double) i);
+
+ gri_mmse_fir_interpolator intr;
+ float inv_nsteps = 1.0 / intr.nsteps ();
+
+ for (unsigned i = 0; i < N; i++){
+ for (unsigned imu = 0; imu <= intr.nsteps (); imu += 1){
+ float expected = test_fcn ((i + 3) + imu * inv_nsteps);
+ float actual = intr.interpolate (&input[i], imu * inv_nsteps);
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (expected, actual, 0.004);
+ // printf ("%9.6f %9.6f %9.6f\n", expected, actual, expected - actual);
+ }
+ }
+}
+
diff --git a/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator.h b/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator.h
new file mode 100644
index 0000000000..85be45e89f
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _QA_GRI_MMSE_FIR_INTERPOLATOR_H_
+#define _QA_GRI_MMSE_FIR_INTERPOLATOR_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gri_mmse_fir_interpolator : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gri_mmse_fir_interpolator);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void t1 ();
+
+};
+
+
+#endif /* _QA_GRI_MMSE_FIR_INTERPOLATOR_H_ */
diff --git a/gnuradio-core/src/lib/filter/short_dotprod_generic.c b/gnuradio-core/src/lib/filter/short_dotprod_generic.c
new file mode 100644
index 0000000000..4fca2e5dd3
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "short_dotprod_generic.h"
+
+
+int
+short_dotprod_generic (const short *input,
+ const short *taps, unsigned n_4_short_blocks)
+{
+ int sum0 = 0;
+ int sum1 = 0;
+ int sum2 = 0;
+ int sum3 = 0;
+
+ do {
+
+ sum0 += input[0] * taps[0];
+ sum1 += input[1] * taps[1];
+ sum2 += input[2] * taps[2];
+ sum3 += input[3] * taps[3];
+
+ input += 4;
+ taps += 4;
+
+ } while (--n_4_short_blocks != 0);
+
+
+ return (sum0 + sum1 + sum2 + sum3);
+}
diff --git a/gnuradio-core/src/lib/filter/short_dotprod_generic.h b/gnuradio-core/src/lib/filter/short_dotprod_generic.h
new file mode 100644
index 0000000000..6e3709ff31
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _SHORT_DOTPROD_GENERIC_H_
+#define _SHORT_DOTPROD_GENERIC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int
+short_dotprod_generic (const short *input,
+ const short *taps, unsigned n_4_short_blocks);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _SHORT_DOTPROD_GENERIC_H_ */
diff --git a/gnuradio-core/src/lib/filter/short_dotprod_mmx.S b/gnuradio-core/src/lib/filter/short_dotprod_mmx.S
new file mode 100644
index 0000000000..7c9ae07818
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/short_dotprod_mmx.S
@@ -0,0 +1,113 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+# SIMD MMX dot product
+# Equivalent to the following C code:
+# long dotprod(signed short *a,signed short *b,int cnt)
+# {
+# long sum = 0;
+# cnt *= 4;
+# while(cnt--)
+# sum += *a++ + *b++;
+# return sum;
+# }
+# a and b should also be 64-bit aligned, or speed will suffer greatly
+# Copyright 1999, Phil Karn KA9Q
+# May be used under the terms of the GNU public license
+
+#include "assembly.h"
+
+
+ .file "short_dotprod_mmx.S"
+ .version "01.01"
+.text
+ .p2align 3
+.globl GLOB_SYMB(short_dotprod_mmx)
+ DEF_FUNC_HEAD(short_dotprod_mmx)
+GLOB_SYMB(short_dotprod_mmx):
+ pushl %ebp
+ movl %esp,%ebp
+ pushl %esi
+ pushl %edi
+ pushl %ecx
+ pushl %ebx
+ movl 8(%ebp),%esi # a
+ movl 12(%ebp),%edi # b
+ movl 16(%ebp),%ecx # cnt
+ pxor %mm0,%mm0 # clear running sum (in two 32-bit halves)
+
+# MMX dot product loop unrolled 4 times, crunching 16 terms per loop
+ .p2align 4
+.Loop1mmx: subl $4,%ecx
+ jl .Loop1Done
+
+ movq (%esi),%mm1 # mm1 = a[3],a[2],a[1],a[0]
+ pmaddwd (%edi),%mm1 # mm1 = b[3]*a[3]+b[2]*a[2],b[1]*a[1]+b[0]*a[0]
+ paddd %mm1,%mm0
+
+ movq 8(%esi),%mm1
+ pmaddwd 8(%edi),%mm1
+ paddd %mm1,%mm0
+
+ movq 16(%esi),%mm1
+ pmaddwd 16(%edi),%mm1
+ paddd %mm1,%mm0
+
+ movq 24(%esi),%mm1
+ addl $32,%esi
+ pmaddwd 24(%edi),%mm1
+ addl $32,%edi
+ paddd %mm1,%mm0
+
+ jmp .Loop1mmx
+.Loop1Done:
+
+ addl $4,%ecx
+
+# MMX dot product loop, not unrolled, crunching 4 terms per loop
+# This could be redone as Duff's Device on the unrolled loop above
+.Loop2: subl $1,%ecx
+ jl .Loop2Done
+
+ movq (%esi),%mm1
+ addl $8,%esi
+ pmaddwd (%edi),%mm1
+ addl $8,%edi
+ paddd %mm1,%mm0
+ jmp .Loop2
+.Loop2Done:
+
+ movd %mm0,%ebx # right-hand word to ebx
+ punpckhdq %mm0,%mm0 # left-hand word to right side of %mm0
+ movd %mm0,%eax
+ addl %ebx,%eax # running sum now in %eax
+ emms # done with MMX
+
+ popl %ebx
+ popl %ecx
+ popl %edi
+ popl %esi
+ movl %ebp,%esp
+ popl %ebp
+ ret
+
+FUNC_TAIL(short_dotprod_mmx)
+ .ident "Hand coded x86 MMX assembly"
diff --git a/gnuradio-core/src/lib/filter/short_dotprod_mmx64.S b/gnuradio-core/src/lib/filter/short_dotprod_mmx64.S
new file mode 100644
index 0000000000..4c46e0ea42
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/short_dotprod_mmx64.S
@@ -0,0 +1,101 @@
+#
+# Copyright 2002,2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+# SIMD MMX dot product
+# Equivalent to the following C code:
+# long dotprod(signed short *a,signed short *b,int cnt)
+# {
+# long sum = 0;
+# cnt *= 4;
+# while(cnt--)
+# sum += *a++ + *b++;
+# return sum;
+# }
+# a and b should also be 64-bit aligned, or speed will suffer greatly
+# Copyright 1999, Phil Karn KA9Q
+# May be used under the terms of the GNU public license
+
+#include "assembly.h"
+
+
+ .file "short_dotprod_mmx64.S"
+ .version "01.01"
+.text
+ .p2align 3
+.globl GLOB_SYMB(short_dotprod_mmx)
+ DEF_FUNC_HEAD(short_dotprod_mmx)
+GLOB_SYMB(short_dotprod_mmx):
+
+ # a: rdi, b: rsi, cnt: rdx
+
+ pxor %mm0,%mm0 # clear running sum (in two 32-bit halves)
+
+# MMX dot product loop unrolled 4 times, crunching 16 terms per loop
+ .p2align 4
+.Loop1mmx: sub $4,%rdx
+ jl .Loop1Done
+
+ movq (%rdi),%mm1 # mm1 = a[3],a[2],a[1],a[0]
+ pmaddwd (%rsi),%mm1 # mm1 = b[3]*a[3]+b[2]*a[2],b[1]*a[1]+b[0]*a[0]
+ paddd %mm1,%mm0
+
+ movq 8(%rdi),%mm1
+ pmaddwd 8(%rsi),%mm1
+ paddd %mm1,%mm0
+
+ movq 16(%rdi),%mm1
+ pmaddwd 16(%rsi),%mm1
+ paddd %mm1,%mm0
+
+ movq 24(%rdi),%mm1
+ add $32,%rdi
+ pmaddwd 24(%rsi),%mm1
+ add $32,%rsi
+ paddd %mm1,%mm0
+
+ jmp .Loop1mmx
+.Loop1Done:
+
+ add $4,%rdx
+
+# MMX dot product loop, not unrolled, crunching 4 terms per loop
+# This could be redone as Duff's Device on the unrolled loop above
+.Loop2: sub $1,%rdx
+ jl .Loop2Done
+
+ movq (%rdi),%mm1
+ add $8,%rdi
+ pmaddwd (%rsi),%mm1
+ add $8,%rsi
+ paddd %mm1,%mm0
+ jmp .Loop2
+.Loop2Done:
+
+ movd %mm0,%edx # right-hand word to edx
+ punpckhdq %mm0,%mm0 # left-hand word to right side of %mm0
+ movd %mm0,%eax
+ addl %edx,%eax # running sum now in %eax
+ emms # done with MMX
+
+ retq
+
+FUNC_TAIL(short_dotprod_mmx)
+ .ident "Hand coded x86_64 MMX assembly"
diff --git a/gnuradio-core/src/lib/filter/short_dotprod_x86.h b/gnuradio-core/src/lib/filter/short_dotprod_x86.h
new file mode 100644
index 0000000000..03b47489e4
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _SHORT_DOTPROD_X86_H_
+#define _SHORT_DOTPROD_X86_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int
+short_dotprod_mmx (const short *input,
+ const short *taps, unsigned n_4_short_blocks);
+
+int
+short_dotprod_sse2 (const short *input,
+ const short *taps, unsigned n_4_short_blocks);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _SHORT_DOTPROD_X86_H_ */
diff --git a/gnuradio-core/src/lib/filter/sse_debug.c b/gnuradio-core/src/lib/filter/sse_debug.c
new file mode 100644
index 0000000000..f27d3930b3
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <stdio.h>
+#include <sse_debug.h>
+#include <string.h>
+
+void
+format_xmm_regs (FILE *f, struct xmm_regs *r)
+{
+ int i;
+
+ for (i = 0; i < 8; i++){
+ union xmm_register *x = &r->xmm[i];
+ fprintf (f, "xmm%d: %08lx %08lx %08lx %08lx", i,
+ x->ul[0], x->ul[1], x->ul[2], x->ul[3]);
+ fprintf (f, " %12g %12g %12g %12g\n",
+ x->f[0], x->f[1], x->f[2], x->f[3]);
+ }
+}
+
+
+void
+get_xmm_regs (struct xmm_regs *x)
+{
+ asm ("movups %%xmm0,0x00(%0); \n"
+ "movups %%xmm1,0x10(%0); \n"
+ "movups %%xmm2,0x20(%0); \n"
+ "movups %%xmm3,0x30(%0); \n"
+ "movups %%xmm4,0x40(%0); \n"
+ "movups %%xmm5,0x50(%0); \n"
+ "movups %%xmm6,0x60(%0); \n"
+ "movups %%xmm7,0x70(%0); \n" : : "r" (x));
+}
+
+void
+dump_xmm_regs (void)
+{
+ struct xmm_regs r;
+
+ get_xmm_regs (&r);
+ format_xmm_regs (stderr, &r);
+}
+
diff --git a/gnuradio-core/src/lib/filter/sse_debug.h b/gnuradio-core/src/lib/filter/sse_debug.h
new file mode 100644
index 0000000000..f356a0e034
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _SSE_DEBUG_H_
+#define _SSE_DEBUG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ union xmm_register {
+ unsigned long ul[4];
+ float f[4];
+ };
+
+ struct xmm_regs {
+ union xmm_register xmm[8];
+ };
+
+ // callable from asm, dumps all xmm regs
+ void dump_xmm_regs (void);
+
+ void get_xmm_regs (struct xmm_regs *x);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _SSE_DEBUG_H_
diff --git a/gnuradio-core/src/lib/filter/sysconfig_generic.cc b/gnuradio-core/src/lib/filter/sysconfig_generic.cc
new file mode 100644
index 0000000000..1cecf49f45
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gr_fir_sysconfig_generic.h>
+
+gr_fir_sysconfig *
+gr_fir_sysconfig_singleton ()
+{
+ static gr_fir_sysconfig *singleton = 0;
+
+ if (singleton)
+ return singleton;
+
+ singleton = new gr_fir_sysconfig_generic ();
+ return singleton;
+}
diff --git a/gnuradio-core/src/lib/filter/sysconfig_x86.cc b/gnuradio-core/src/lib/filter/sysconfig_x86.cc
new file mode 100644
index 0000000000..d2c31612ac
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_sysconfig_x86.h>
+
+gr_fir_sysconfig *
+gr_fir_sysconfig_singleton ()
+{
+ static gr_fir_sysconfig *singleton = 0;
+
+ if (singleton)
+ return singleton;
+
+ singleton = new gr_fir_sysconfig_x86 ();
+ return singleton;
+}
diff --git a/gnuradio-core/src/lib/g72x/Makefile.am b/gnuradio-core/src/lib/g72x/Makefile.am
new file mode 100644
index 0000000000..c8ba3e8dc4
--- /dev/null
+++ b/gnuradio-core/src/lib/g72x/Makefile.am
@@ -0,0 +1,27 @@
+#
+# Copyright 2001 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+include $(top_srcdir)/Makefile.common
+
+noinst_LTLIBRARIES = libccitt.la
+libccitt_la_SOURCES = g711.c g72x.c g721.c g723_24.c g723_40.c g72x.h
+
+EXTRA_DIST = encode.c decode.c
diff --git a/gnuradio-core/src/lib/g72x/README b/gnuradio-core/src/lib/g72x/README
new file mode 100644
index 0000000000..23b0e7dd50
--- /dev/null
+++ b/gnuradio-core/src/lib/g72x/README
@@ -0,0 +1,94 @@
+The files in this directory comprise ANSI-C language reference implementations
+of the CCITT (International Telegraph and Telephone Consultative Committee)
+G.711, G.721 and G.723 voice compressions. They have been tested on Sun
+SPARCstations and passed 82 out of 84 test vectors published by CCITT
+(Dec. 20, 1988) for G.721 and G.723. [The two remaining test vectors,
+which the G.721 decoder implementation for u-law samples did not pass,
+may be in error because they are identical to two other vectors for G.723_40.]
+
+This source code is released by Sun Microsystems, Inc. to the public domain.
+Please give your acknowledgement in product literature if this code is used
+in your product implementation.
+
+Sun Microsystems supports some CCITT audio formats in Solaris 2.0 system
+software. However, Sun's implementations have been optimized for higher
+performance on SPARCstations.
+
+
+The source files for CCITT conversion routines in this directory are:
+
+ g72x.h header file for g721.c, g723_24.c and g723_40.c
+ g711.c CCITT G.711 u-law and A-law compression
+ g72x.c common denominator of G.721 and G.723 ADPCM codes
+ g721.c CCITT G.721 32Kbps ADPCM coder (with g72x.c)
+ g723_24.c CCITT G.723 24Kbps ADPCM coder (with g72x.c)
+ g723_40.c CCITT G.723 40Kbps ADPCM coder (with g72x.c)
+
+
+Simple conversions between u-law, A-law, and 16-bit linear PCM are invoked
+as follows:
+
+ unsigned char ucode, acode;
+ short pcm_val;
+
+ ucode = linear2ulaw(pcm_val);
+ ucode = alaw2ulaw(acode);
+
+ acode = linear2alaw(pcm_val);
+ acode = ulaw2alaw(ucode);
+
+ pcm_val = ulaw2linear(ucode);
+ pcm_val = alaw2linear(acode);
+
+
+The other CCITT compression routines are invoked as follows:
+
+ #include "g72x.h"
+
+ struct g72x_state state;
+ int sample, code;
+
+ g72x_init_state(&state);
+ code = {g721,g723_24,g723_40}_encoder(sample, coding, &state);
+ sample = {g721,g723_24,g723_40}_decoder(code, coding, &state);
+
+where
+ coding = AUDIO_ENCODING_ULAW for 8-bit u-law samples
+ AUDIO_ENCODING_ALAW for 8-bit A-law samples
+ AUDIO_ENCODING_LINEAR for 16-bit linear PCM samples
+
+
+
+This directory also includes the following sample programs:
+
+ encode.c CCITT ADPCM encoder
+ decode.c CCITT ADPCM decoder
+ Makefile makefile for the sample programs
+
+
+The sample programs contain examples of how to call the various compression
+routines and pack/unpack the bits. The sample programs read byte streams from
+stdin and write to stdout. The input/output data is raw data (no file header
+or other identifying information is embedded). The sample programs are
+invoked as follows:
+
+ encode [-3|4|5] [-a|u|l] <infile >outfile
+ decode [-3|4|5] [-a|u|l] <infile >outfile
+where:
+ -3 encode to (decode from) G.723 24kbps (3-bit) data
+ -4 encode to (decode from) G.721 32kbps (4-bit) data [the default]
+ -5 encode to (decode from) G.723 40kbps (5-bit) data
+ -a encode from (decode to) A-law data
+ -u encode from (decode to) u-law data [the default]
+ -l encode from (decode to) 16-bit linear data
+
+Examples:
+ # Read 16-bit linear and output G.721
+ encode -4 -l <pcmfile >g721file
+
+ # Read 40Kbps G.723 and output A-law
+ decode -5 -a <g723file >alawfile
+
+ # Compress and then decompress u-law data using 24Kbps G.723
+ encode -3 <ulawin | deoced -3 >ulawout
+
diff --git a/gnuradio-core/src/lib/g72x/decode.c b/gnuradio-core/src/lib/g72x/decode.c
new file mode 100644
index 0000000000..cf8c739c55
--- /dev/null
+++ b/gnuradio-core/src/lib/g72x/decode.c
@@ -0,0 +1,113 @@
+/*
+ * decode.c
+ *
+ * CCITT ADPCM decoder
+ *
+ * Usage : decode [-3|4|5] [-a|u|l] < infile > outfile
+ */
+#include <stdio.h>
+#include "g72x.h"
+
+
+/*
+ * Unpack input codes and pass them back as bytes.
+ * Returns 1 if there is residual input, returns -1 if eof, else returns 0.
+ */
+int
+unpack_input(
+ unsigned char *code,
+ int bits)
+{
+ static unsigned int in_buffer = 0;
+ static int in_bits = 0;
+ unsigned char in_byte;
+
+ if (in_bits < bits) {
+ if (fread(&in_byte, sizeof (char), 1, stdin) != 1) {
+ *code = 0;
+ return (-1);
+ }
+ in_buffer |= (in_byte << in_bits);
+ in_bits += 8;
+ }
+ *code = in_buffer & ((1 << bits) - 1);
+ in_buffer >>= bits;
+ in_bits -= bits;
+ return (in_bits > 0);
+}
+
+
+main(
+ int argc,
+ char **argv)
+{
+ short sample;
+ unsigned char code;
+ int n;
+ struct g72x_state state;
+ int out_coding;
+ int out_size;
+ int (*dec_routine)();
+ int dec_bits;
+
+ g72x_init_state(&state);
+ out_coding = AUDIO_ENCODING_ULAW;
+ out_size = sizeof (char);
+ dec_routine = g721_decoder;
+ dec_bits = 4;
+
+ /* Process encoding argument, if any */
+ while ((argc > 1) && (argv[1][0] == '-')) {
+ switch (argv[1][1]) {
+ case '3':
+ dec_routine = g723_24_decoder;
+ dec_bits = 3;
+ break;
+ case '4':
+ dec_routine = g721_decoder;
+ dec_bits = 4;
+ break;
+ case '5':
+ dec_routine = g723_40_decoder;
+ dec_bits = 5;
+ break;
+ case 'u':
+ out_coding = AUDIO_ENCODING_ULAW;
+ out_size = sizeof (char);
+ break;
+ case 'a':
+ out_coding = AUDIO_ENCODING_ALAW;
+ out_size = sizeof (char);
+ break;
+ case 'l':
+ out_coding = AUDIO_ENCODING_LINEAR;
+ out_size = sizeof (short);
+ break;
+ default:
+fprintf(stderr, "CCITT ADPCM Decoder -- usage:\n");
+fprintf(stderr, "\tdecode [-3|4|5] [-a|u|l] < infile > outfile\n");
+fprintf(stderr, "where:\n");
+fprintf(stderr, "\t-3\tProcess G.723 24kbps (3-bit) input data\n");
+fprintf(stderr, "\t-4\tProcess G.721 32kbps (4-bit) input data [default]\n");
+fprintf(stderr, "\t-5\tProcess G.723 40kbps (5-bit) input data\n");
+fprintf(stderr, "\t-a\tGenerate 8-bit A-law data\n");
+fprintf(stderr, "\t-u\tGenerate 8-bit u-law data [default]\n");
+fprintf(stderr, "\t-l\tGenerate 16-bit linear PCM data\n");
+ exit(1);
+ }
+ argc--;
+ argv++;
+ }
+
+ /* Read and unpack input codes and process them */
+ while (unpack_input(&code, dec_bits) >= 0) {
+ sample = (*dec_routine)(code, out_coding, &state);
+ if (out_size == 2) {
+ fwrite(&sample, out_size, 1, stdout);
+ } else {
+ code = (unsigned char)sample;
+ fwrite(&code, out_size, 1, stdout);
+ }
+ }
+ fclose(stdout);
+}
diff --git a/gnuradio-core/src/lib/g72x/encode.c b/gnuradio-core/src/lib/g72x/encode.c
new file mode 100644
index 0000000000..e744828692
--- /dev/null
+++ b/gnuradio-core/src/lib/g72x/encode.c
@@ -0,0 +1,119 @@
+/*
+ * encode.c
+ *
+ * CCITT ADPCM encoder
+ *
+ * Usage : encode [-3|4|5] [-a|u|l] < infile > outfile
+ */
+#include <stdio.h>
+#include "g72x.h"
+
+
+/*
+ * Pack output codes into bytes and write them to stdout.
+ * Returns 1 if there is residual output, else returns 0.
+ */
+int
+pack_output(
+ unsigned code,
+ int bits)
+{
+ static unsigned int out_buffer = 0;
+ static int out_bits = 0;
+ unsigned char out_byte;
+
+ out_buffer |= (code << out_bits);
+ out_bits += bits;
+ if (out_bits >= 8) {
+ out_byte = out_buffer & 0xff;
+ out_bits -= 8;
+ out_buffer >>= 8;
+ fwrite(&out_byte, sizeof (char), 1, stdout);
+ }
+ return (out_bits > 0);
+}
+
+
+main(
+ int argc,
+ char **argv)
+{
+ struct g72x_state state;
+ unsigned char sample_char;
+ short sample_short;
+ unsigned char code;
+ int resid;
+ int in_coding;
+ int in_size;
+ unsigned *in_buf;
+ int (*enc_routine)();
+ int enc_bits;
+
+ g72x_init_state(&state);
+
+ /* Set defaults to u-law input, G.721 output */
+ in_coding = AUDIO_ENCODING_ULAW;
+ in_size = sizeof (char);
+ in_buf = (unsigned *)&sample_char;
+ enc_routine = g721_encoder;
+ enc_bits = 4;
+
+ /* Process encoding argument, if any */
+ while ((argc > 1) && (argv[1][0] == '-')) {
+ switch (argv[1][1]) {
+ case '3':
+ enc_routine = g723_24_encoder;
+ enc_bits = 3;
+ break;
+ case '4':
+ enc_routine = g721_encoder;
+ enc_bits = 4;
+ break;
+ case '5':
+ enc_routine = g723_40_encoder;
+ enc_bits = 5;
+ break;
+ case 'u':
+ in_coding = AUDIO_ENCODING_ULAW;
+ in_size = sizeof (char);
+ in_buf = (unsigned *)&sample_char;
+ break;
+ case 'a':
+ in_coding = AUDIO_ENCODING_ALAW;
+ in_size = sizeof (char);
+ in_buf = (unsigned *)&sample_char;
+ break;
+ case 'l':
+ in_coding = AUDIO_ENCODING_LINEAR;
+ in_size = sizeof (short);
+ in_buf = (unsigned *)&sample_short;
+ break;
+ default:
+fprintf(stderr, "CCITT ADPCM Encoder -- usage:\n");
+fprintf(stderr, "\tencode [-3|4|5] [-a|u|l] < infile > outfile\n");
+fprintf(stderr, "where:\n");
+fprintf(stderr, "\t-3\tGenerate G.723 24kbps (3-bit) data\n");
+fprintf(stderr, "\t-4\tGenerate G.721 32kbps (4-bit) data [default]\n");
+fprintf(stderr, "\t-5\tGenerate G.723 40kbps (5-bit) data\n");
+fprintf(stderr, "\t-a\tProcess 8-bit A-law input data\n");
+fprintf(stderr, "\t-u\tProcess 8-bit u-law input data [default]\n");
+fprintf(stderr, "\t-l\tProcess 16-bit linear PCM input data\n");
+ exit(1);
+ }
+ argc--;
+ argv++;
+ }
+
+ /* Read input file and process */
+ while (fread(in_buf, in_size, 1, stdin) == 1) {
+ code = (*enc_routine)(in_size == 2 ? sample_short : sample_char,
+ in_coding, &state);
+ resid = pack_output(code, enc_bits);
+ }
+
+ /* Write zero codes until all residual codes are written out */
+ while (resid) {
+ resid = pack_output(0, enc_bits);
+ }
+ fclose(stdout);
+}
diff --git a/gnuradio-core/src/lib/g72x/g711.c b/gnuradio-core/src/lib/g72x/g711.c
new file mode 100644
index 0000000000..d4d60a5c26
--- /dev/null
+++ b/gnuradio-core/src/lib/g72x/g711.c
@@ -0,0 +1,283 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use. Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * g711.c
+ *
+ * u-law, A-law and linear PCM conversions.
+ */
+#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
+#define QUANT_MASK (0xf) /* Quantization field mask. */
+#define NSEGS (8) /* Number of A-law segments. */
+#define SEG_SHIFT (4) /* Left shift for segment number. */
+#define SEG_MASK (0x70) /* Segment field mask. */
+
+static short seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF,
+ 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
+
+/* copy from CCITT G.711 specifications */
+unsigned char _u2a[128] = { /* u- to A-law conversions */
+ 1, 1, 2, 2, 3, 3, 4, 4,
+ 5, 5, 6, 6, 7, 7, 8, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 27, 29, 31, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, 42, 43, 44,
+ 46, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62,
+ 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79,
+ 81, 82, 83, 84, 85, 86, 87, 88,
+ 89, 90, 91, 92, 93, 94, 95, 96,
+ 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112,
+ 113, 114, 115, 116, 117, 118, 119, 120,
+ 121, 122, 123, 124, 125, 126, 127, 128};
+
+unsigned char _a2u[128] = { /* A- to u-law conversions */
+ 1, 3, 5, 7, 9, 11, 13, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 32, 33, 33, 34, 34, 35, 35,
+ 36, 37, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 48, 49, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 59, 60, 61, 62, 63, 64, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 74, 75, 76, 77, 78, 79, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127};
+
+static int
+search(
+ int val,
+ short *table,
+ int size)
+{
+ int i;
+
+ for (i = 0; i < size; i++) {
+ if (val <= *table++)
+ return (i);
+ }
+ return (size);
+}
+
+/*
+ * linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
+ *
+ * linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
+ *
+ * Linear Input Code Compressed Code
+ * ------------------------ ---------------
+ * 0000000wxyza 000wxyz
+ * 0000001wxyza 001wxyz
+ * 000001wxyzab 010wxyz
+ * 00001wxyzabc 011wxyz
+ * 0001wxyzabcd 100wxyz
+ * 001wxyzabcde 101wxyz
+ * 01wxyzabcdef 110wxyz
+ * 1wxyzabcdefg 111wxyz
+ *
+ * For further information see John C. Bellamy's Digital Telephony, 1982,
+ * John Wiley & Sons, pps 98-111 and 472-476.
+ */
+unsigned char
+linear2alaw(
+ int pcm_val) /* 2's complement (16-bit range) */
+{
+ int mask;
+ int seg;
+ unsigned char aval;
+
+ if (pcm_val >= 0) {
+ mask = 0xD5; /* sign (7th) bit = 1 */
+ } else {
+ mask = 0x55; /* sign bit = 0 */
+ pcm_val = -pcm_val - 8;
+ }
+
+ /* Convert the scaled magnitude to segment number. */
+ seg = search(pcm_val, seg_end, 8);
+
+ /* Combine the sign, segment, and quantization bits. */
+
+ if (seg >= 8) /* out of range, return maximum value. */
+ return (0x7F ^ mask);
+ else {
+ aval = seg << SEG_SHIFT;
+ if (seg < 2)
+ aval |= (pcm_val >> 4) & QUANT_MASK;
+ else
+ aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
+ return (aval ^ mask);
+ }
+}
+
+/*
+ * alaw2linear() - Convert an A-law value to 16-bit linear PCM
+ *
+ */
+int
+alaw2linear(
+ unsigned char a_val)
+{
+ int t;
+ int seg;
+
+ a_val ^= 0x55;
+
+ t = (a_val & QUANT_MASK) << 4;
+ seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
+ switch (seg) {
+ case 0:
+ t += 8;
+ break;
+ case 1:
+ t += 0x108;
+ break;
+ default:
+ t += 0x108;
+ t <<= seg - 1;
+ }
+ return ((a_val & SIGN_BIT) ? t : -t);
+}
+
+#define BIAS (0x84) /* Bias for linear code. */
+
+/*
+ * linear2ulaw() - Convert a linear PCM value to u-law
+ *
+ * In order to simplify the encoding process, the original linear magnitude
+ * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
+ * (33 - 8191). The result can be seen in the following encoding table:
+ *
+ * Biased Linear Input Code Compressed Code
+ * ------------------------ ---------------
+ * 00000001wxyza 000wxyz
+ * 0000001wxyzab 001wxyz
+ * 000001wxyzabc 010wxyz
+ * 00001wxyzabcd 011wxyz
+ * 0001wxyzabcde 100wxyz
+ * 001wxyzabcdef 101wxyz
+ * 01wxyzabcdefg 110wxyz
+ * 1wxyzabcdefgh 111wxyz
+ *
+ * Each biased linear code has a leading 1 which identifies the segment
+ * number. The value of the segment number is equal to 7 minus the number
+ * of leading 0's. The quantization interval is directly available as the
+ * four bits wxyz. * The trailing bits (a - h) are ignored.
+ *
+ * Ordinarily the complement of the resulting code word is used for
+ * transmission, and so the code word is complemented before it is returned.
+ *
+ * For further information see John C. Bellamy's Digital Telephony, 1982,
+ * John Wiley & Sons, pps 98-111 and 472-476.
+ */
+unsigned char
+linear2ulaw(
+ int pcm_val) /* 2's complement (16-bit range) */
+{
+ int mask;
+ int seg;
+ unsigned char uval;
+
+ /* Get the sign and the magnitude of the value. */
+ if (pcm_val < 0) {
+ pcm_val = BIAS - pcm_val;
+ mask = 0x7F;
+ } else {
+ pcm_val += BIAS;
+ mask = 0xFF;
+ }
+
+ /* Convert the scaled magnitude to segment number. */
+ seg = search(pcm_val, seg_end, 8);
+
+ /*
+ * Combine the sign, segment, quantization bits;
+ * and complement the code word.
+ */
+ if (seg >= 8) /* out of range, return maximum value. */
+ return (0x7F ^ mask);
+ else {
+ uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF);
+ return (uval ^ mask);
+ }
+
+}
+
+/*
+ * ulaw2linear() - Convert a u-law value to 16-bit linear PCM
+ *
+ * First, a biased linear code is derived from the code word. An unbiased
+ * output can then be obtained by subtracting 33 from the biased code.
+ *
+ * Note that this function expects to be passed the complement of the
+ * original code word. This is in keeping with ISDN conventions.
+ */
+int
+ulaw2linear(
+ unsigned char u_val)
+{
+ int t;
+
+ /* Complement to obtain normal u-law value. */
+ u_val = ~u_val;
+
+ /*
+ * Extract and bias the quantization bits. Then
+ * shift up by the segment number and subtract out the bias.
+ */
+ t = ((u_val & QUANT_MASK) << 3) + BIAS;
+ t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
+
+ return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
+}
+
+/* A-law to u-law conversion */
+unsigned char
+alaw2ulaw(
+ unsigned char aval)
+{
+ aval &= 0xff;
+ return ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) :
+ (0x7F ^ _a2u[aval ^ 0x55]));
+}
+
+/* u-law to A-law conversion */
+unsigned char
+ulaw2alaw(
+ unsigned char uval)
+{
+ uval &= 0xff;
+ return ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) :
+ (0x55 ^ (_u2a[0x7F ^ uval] - 1)));
+}
diff --git a/gnuradio-core/src/lib/g72x/g721.c b/gnuradio-core/src/lib/g72x/g721.c
new file mode 100644
index 0000000000..445f177e84
--- /dev/null
+++ b/gnuradio-core/src/lib/g72x/g721.c
@@ -0,0 +1,173 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use. Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * g721.c
+ *
+ * Description:
+ *
+ * g721_encoder(), g721_decoder()
+ *
+ * These routines comprise an implementation of the CCITT G.721 ADPCM
+ * coding algorithm. Essentially, this implementation is identical to
+ * the bit level description except for a few deviations which
+ * take advantage of work station attributes, such as hardware 2's
+ * complement arithmetic and large memory. Specifically, certain time
+ * consuming operations such as multiplications are replaced
+ * with lookup tables and software 2's complement operations are
+ * replaced with hardware 2's complement.
+ *
+ * The deviation from the bit level specification (lookup tables)
+ * preserves the bit level performance specifications.
+ *
+ * As outlined in the G.721 Recommendation, the algorithm is broken
+ * down into modules. Each section of code below is preceded by
+ * the name of the module which it is implementing.
+ *
+ */
+#include "g72x.h"
+
+static short qtab_721[7] = {-124, 80, 178, 246, 300, 349, 400};
+/*
+ * Maps G.721 code word to reconstructed scale factor normalized log
+ * magnitude values.
+ */
+static short _dqlntab[16] = {-2048, 4, 135, 213, 273, 323, 373, 425,
+ 425, 373, 323, 273, 213, 135, 4, -2048};
+
+/* Maps G.721 code word to log of scale factor multiplier. */
+static short _witab[16] = {-12, 18, 41, 64, 112, 198, 355, 1122,
+ 1122, 355, 198, 112, 64, 41, 18, -12};
+/*
+ * Maps G.721 code words to a set of values whose long and short
+ * term averages are computed and then compared to give an indication
+ * how stationary (steady state) the signal is.
+ */
+static short _fitab[16] = {0, 0, 0, 0x200, 0x200, 0x200, 0x600, 0xE00,
+ 0xE00, 0x600, 0x200, 0x200, 0x200, 0, 0, 0};
+
+/*
+ * g721_encoder()
+ *
+ * Encodes the input vale of linear PCM, A-law or u-law data sl and returns
+ * the resulting code. -1 is returned for unknown input coding value.
+ */
+int
+g721_encoder(
+ int sl,
+ int in_coding,
+ struct g72x_state *state_ptr)
+{
+ short sezi, se, sez; /* ACCUM */
+ short d; /* SUBTA */
+ short sr; /* ADDB */
+ short y; /* MIX */
+ short dqsez; /* ADDC */
+ short dq, i;
+
+ switch (in_coding) { /* linearize input sample to 14-bit PCM */
+ case AUDIO_ENCODING_ALAW:
+ sl = alaw2linear(sl) >> 2;
+ break;
+ case AUDIO_ENCODING_ULAW:
+ sl = ulaw2linear(sl) >> 2;
+ break;
+ case AUDIO_ENCODING_LINEAR:
+ sl >>= 2; /* 14-bit dynamic range */
+ break;
+ default:
+ return (-1);
+ }
+
+ sezi = predictor_zero(state_ptr);
+ sez = sezi >> 1;
+ se = (sezi + predictor_pole(state_ptr)) >> 1; /* estimated signal */
+
+ d = sl - se; /* estimation difference */
+
+ /* quantize the prediction difference */
+ y = step_size(state_ptr); /* quantizer step size */
+ i = quantize(d, y, qtab_721, 7); /* i = ADPCM code */
+
+ dq = reconstruct(i & 8, _dqlntab[i], y); /* quantized est diff */
+
+ sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconst. signal */
+
+ dqsez = sr + sez - se; /* pole prediction diff. */
+
+ update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr);
+
+ return (i);
+}
+
+/*
+ * g721_decoder()
+ *
+ * Description:
+ *
+ * Decodes a 4-bit code of G.721 encoded data of i and
+ * returns the resulting linear PCM, A-law or u-law value.
+ * return -1 for unknown out_coding value.
+ */
+int
+g721_decoder(
+ int i,
+ int out_coding,
+ struct g72x_state *state_ptr)
+{
+ short sezi, sei, sez, se; /* ACCUM */
+ short y; /* MIX */
+ short sr; /* ADDB */
+ short dq;
+ short dqsez;
+
+ i &= 0x0f; /* mask to get proper bits */
+ sezi = predictor_zero(state_ptr);
+ sez = sezi >> 1;
+ sei = sezi + predictor_pole(state_ptr);
+ se = sei >> 1; /* se = estimated signal */
+
+ y = step_size(state_ptr); /* dynamic quantizer step size */
+
+ dq = reconstruct(i & 0x08, _dqlntab[i], y); /* quantized diff. */
+
+ sr = (dq < 0) ? (se - (dq & 0x3FFF)) : se + dq; /* reconst. signal */
+
+ dqsez = sr - se + sez; /* pole prediction diff. */
+
+ update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr);
+
+ switch (out_coding) {
+ case AUDIO_ENCODING_ALAW:
+ return (tandem_adjust_alaw(sr, se, y, i, 8, qtab_721));
+ case AUDIO_ENCODING_ULAW:
+ return (tandem_adjust_ulaw(sr, se, y, i, 8, qtab_721));
+ case AUDIO_ENCODING_LINEAR:
+ return (sr << 2); /* sr was 14-bit dynamic range */
+ default:
+ return (-1);
+ }
+}
diff --git a/gnuradio-core/src/lib/g72x/g723_24.c b/gnuradio-core/src/lib/g72x/g723_24.c
new file mode 100644
index 0000000000..452f4daebe
--- /dev/null
+++ b/gnuradio-core/src/lib/g72x/g723_24.c
@@ -0,0 +1,158 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use. Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * g723_24.c
+ *
+ * Description:
+ *
+ * g723_24_encoder(), g723_24_decoder()
+ *
+ * These routines comprise an implementation of the CCITT G.723 24 Kbps
+ * ADPCM coding algorithm. Essentially, this implementation is identical to
+ * the bit level description except for a few deviations which take advantage
+ * of workstation attributes, such as hardware 2's complement arithmetic.
+ *
+ */
+#include "g72x.h"
+
+/*
+ * Maps G.723_24 code word to reconstructed scale factor normalized log
+ * magnitude values.
+ */
+static short _dqlntab[8] = {-2048, 135, 273, 373, 373, 273, 135, -2048};
+
+/* Maps G.723_24 code word to log of scale factor multiplier. */
+static short _witab[8] = {-128, 960, 4384, 18624, 18624, 4384, 960, -128};
+
+/*
+ * Maps G.723_24 code words to a set of values whose long and short
+ * term averages are computed and then compared to give an indication
+ * how stationary (steady state) the signal is.
+ */
+static short _fitab[8] = {0, 0x200, 0x400, 0xE00, 0xE00, 0x400, 0x200, 0};
+
+static short qtab_723_24[3] = {8, 218, 331};
+
+/*
+ * g723_24_encoder()
+ *
+ * Encodes a linear PCM, A-law or u-law input sample and returns its 3-bit code.
+ * Returns -1 if invalid input coding value.
+ */
+int
+g723_24_encoder(
+ int sl,
+ int in_coding,
+ struct g72x_state *state_ptr)
+{
+ short sei, sezi, se, sez; /* ACCUM */
+ short d; /* SUBTA */
+ short y; /* MIX */
+ short sr; /* ADDB */
+ short dqsez; /* ADDC */
+ short dq, i;
+
+ switch (in_coding) { /* linearize input sample to 14-bit PCM */
+ case AUDIO_ENCODING_ALAW:
+ sl = alaw2linear(sl) >> 2;
+ break;
+ case AUDIO_ENCODING_ULAW:
+ sl = ulaw2linear(sl) >> 2;
+ break;
+ case AUDIO_ENCODING_LINEAR:
+ sl >>= 2; /* sl of 14-bit dynamic range */
+ break;
+ default:
+ return (-1);
+ }
+
+ sezi = predictor_zero(state_ptr);
+ sez = sezi >> 1;
+ sei = sezi + predictor_pole(state_ptr);
+ se = sei >> 1; /* se = estimated signal */
+
+ d = sl - se; /* d = estimation diff. */
+
+ /* quantize prediction difference d */
+ y = step_size(state_ptr); /* quantizer step size */
+ i = quantize(d, y, qtab_723_24, 3); /* i = ADPCM code */
+ dq = reconstruct(i & 4, _dqlntab[i], y); /* quantized diff. */
+
+ sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconstructed signal */
+
+ dqsez = sr + sez - se; /* pole prediction diff. */
+
+ update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
+
+ return (i);
+}
+
+/*
+ * g723_24_decoder()
+ *
+ * Decodes a 3-bit CCITT G.723_24 ADPCM code and returns
+ * the resulting 16-bit linear PCM, A-law or u-law sample value.
+ * -1 is returned if the output coding is unknown.
+ */
+int
+g723_24_decoder(
+ int i,
+ int out_coding,
+ struct g72x_state *state_ptr)
+{
+ short sezi, sei, sez, se; /* ACCUM */
+ short y; /* MIX */
+ short sr; /* ADDB */
+ short dq;
+ short dqsez;
+
+ i &= 0x07; /* mask to get proper bits */
+ sezi = predictor_zero(state_ptr);
+ sez = sezi >> 1;
+ sei = sezi + predictor_pole(state_ptr);
+ se = sei >> 1; /* se = estimated signal */
+
+ y = step_size(state_ptr); /* adaptive quantizer step size */
+ dq = reconstruct(i & 0x04, _dqlntab[i], y); /* unquantize pred diff */
+
+ sr = (dq < 0) ? (se - (dq & 0x3FFF)) : (se + dq); /* reconst. signal */
+
+ dqsez = sr - se + sez; /* pole prediction diff. */
+
+ update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
+
+ switch (out_coding) {
+ case AUDIO_ENCODING_ALAW:
+ return (tandem_adjust_alaw(sr, se, y, i, 4, qtab_723_24));
+ case AUDIO_ENCODING_ULAW:
+ return (tandem_adjust_ulaw(sr, se, y, i, 4, qtab_723_24));
+ case AUDIO_ENCODING_LINEAR:
+ return (sr << 2); /* sr was of 14-bit dynamic range */
+ default:
+ return (-1);
+ }
+}
diff --git a/gnuradio-core/src/lib/g72x/g723_40.c b/gnuradio-core/src/lib/g72x/g723_40.c
new file mode 100644
index 0000000000..4858baf40b
--- /dev/null
+++ b/gnuradio-core/src/lib/g72x/g723_40.c
@@ -0,0 +1,178 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use. Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * g723_40.c
+ *
+ * Description:
+ *
+ * g723_40_encoder(), g723_40_decoder()
+ *
+ * These routines comprise an implementation of the CCITT G.723 40Kbps
+ * ADPCM coding algorithm. Essentially, this implementation is identical to
+ * the bit level description except for a few deviations which
+ * take advantage of workstation attributes, such as hardware 2's
+ * complement arithmetic.
+ *
+ * The deviation from the bit level specification (lookup tables),
+ * preserves the bit level performance specifications.
+ *
+ * As outlined in the G.723 Recommendation, the algorithm is broken
+ * down into modules. Each section of code below is preceded by
+ * the name of the module which it is implementing.
+ *
+ */
+#include "g72x.h"
+
+/*
+ * Maps G.723_40 code word to ructeconstructed scale factor normalized log
+ * magnitude values.
+ */
+static short _dqlntab[32] = {-2048, -66, 28, 104, 169, 224, 274, 318,
+ 358, 395, 429, 459, 488, 514, 539, 566,
+ 566, 539, 514, 488, 459, 429, 395, 358,
+ 318, 274, 224, 169, 104, 28, -66, -2048};
+
+/* Maps G.723_40 code word to log of scale factor multiplier. */
+static short _witab[32] = {448, 448, 768, 1248, 1280, 1312, 1856, 3200,
+ 4512, 5728, 7008, 8960, 11456, 14080, 16928, 22272,
+ 22272, 16928, 14080, 11456, 8960, 7008, 5728, 4512,
+ 3200, 1856, 1312, 1280, 1248, 768, 448, 448};
+
+/*
+ * Maps G.723_40 code words to a set of values whose long and short
+ * term averages are computed and then compared to give an indication
+ * how stationary (steady state) the signal is.
+ */
+static short _fitab[32] = {0, 0, 0, 0, 0, 0x200, 0x200, 0x200,
+ 0x200, 0x200, 0x400, 0x600, 0x800, 0xA00, 0xC00, 0xC00,
+ 0xC00, 0xC00, 0xA00, 0x800, 0x600, 0x400, 0x200, 0x200,
+ 0x200, 0x200, 0x200, 0, 0, 0, 0, 0};
+
+static short qtab_723_40[15] = {-122, -16, 68, 139, 198, 250, 298, 339,
+ 378, 413, 445, 475, 502, 528, 553};
+
+/*
+ * g723_40_encoder()
+ *
+ * Encodes a 16-bit linear PCM, A-law or u-law input sample and retuens
+ * the resulting 5-bit CCITT G.723 40Kbps code.
+ * Returns -1 if the input coding value is invalid.
+ */
+int
+g723_40_encoder(
+ int sl,
+ int in_coding,
+ struct g72x_state *state_ptr)
+{
+ short sei, sezi, se, sez; /* ACCUM */
+ short d; /* SUBTA */
+ short y; /* MIX */
+ short sr; /* ADDB */
+ short dqsez; /* ADDC */
+ short dq, i;
+
+ switch (in_coding) { /* linearize input sample to 14-bit PCM */
+ case AUDIO_ENCODING_ALAW:
+ sl = alaw2linear(sl) >> 2;
+ break;
+ case AUDIO_ENCODING_ULAW:
+ sl = ulaw2linear(sl) >> 2;
+ break;
+ case AUDIO_ENCODING_LINEAR:
+ sl >>= 2; /* sl of 14-bit dynamic range */
+ break;
+ default:
+ return (-1);
+ }
+
+ sezi = predictor_zero(state_ptr);
+ sez = sezi >> 1;
+ sei = sezi + predictor_pole(state_ptr);
+ se = sei >> 1; /* se = estimated signal */
+
+ d = sl - se; /* d = estimation difference */
+
+ /* quantize prediction difference */
+ y = step_size(state_ptr); /* adaptive quantizer step size */
+ i = quantize(d, y, qtab_723_40, 15); /* i = ADPCM code */
+
+ dq = reconstruct(i & 0x10, _dqlntab[i], y); /* quantized diff */
+
+ sr = (dq < 0) ? se - (dq & 0x7FFF) : se + dq; /* reconstructed signal */
+
+ dqsez = sr + sez - se; /* dqsez = pole prediction diff. */
+
+ update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
+
+ return (i);
+}
+
+/*
+ * g723_40_decoder()
+ *
+ * Decodes a 5-bit CCITT G.723 40Kbps code and returns
+ * the resulting 16-bit linear PCM, A-law or u-law sample value.
+ * -1 is returned if the output coding is unknown.
+ */
+int
+g723_40_decoder(
+ int i,
+ int out_coding,
+ struct g72x_state *state_ptr)
+{
+ short sezi, sei, sez, se; /* ACCUM */
+ short y; /* MIX */
+ short sr; /* ADDB */
+ short dq;
+ short dqsez;
+
+ i &= 0x1f; /* mask to get proper bits */
+ sezi = predictor_zero(state_ptr);
+ sez = sezi >> 1;
+ sei = sezi + predictor_pole(state_ptr);
+ se = sei >> 1; /* se = estimated signal */
+
+ y = step_size(state_ptr); /* adaptive quantizer step size */
+ dq = reconstruct(i & 0x10, _dqlntab[i], y); /* estimation diff. */
+
+ sr = (dq < 0) ? (se - (dq & 0x7FFF)) : (se + dq); /* reconst. signal */
+
+ dqsez = sr - se + sez; /* pole prediction diff. */
+
+ update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
+
+ switch (out_coding) {
+ case AUDIO_ENCODING_ALAW:
+ return (tandem_adjust_alaw(sr, se, y, i, 0x10, qtab_723_40));
+ case AUDIO_ENCODING_ULAW:
+ return (tandem_adjust_ulaw(sr, se, y, i, 0x10, qtab_723_40));
+ case AUDIO_ENCODING_LINEAR:
+ return (sr << 2); /* sr was of 14-bit dynamic range */
+ default:
+ return (-1);
+ }
+}
diff --git a/gnuradio-core/src/lib/g72x/g72x.c b/gnuradio-core/src/lib/g72x/g72x.c
new file mode 100644
index 0000000000..9a823c7555
--- /dev/null
+++ b/gnuradio-core/src/lib/g72x/g72x.c
@@ -0,0 +1,576 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use. Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#include <stdlib.h>
+/*
+ * g72x.c
+ *
+ * Common routines for G.721 and G.723 conversions.
+ */
+
+#include "g72x.h"
+
+static short power2[15] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80,
+ 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000};
+
+/*
+ * quan()
+ *
+ * quantizes the input val against the table of size short integers.
+ * It returns i if table[i - 1] <= val < table[i].
+ *
+ * Using linear search for simple coding.
+ */
+static int
+quan(
+ int val,
+ short *table,
+ int size)
+{
+ int i;
+
+ for (i = 0; i < size; i++)
+ if (val < *table++)
+ break;
+ return (i);
+}
+
+/*
+ * fmult()
+ *
+ * returns the integer product of the 14-bit integer "an" and
+ * "floating point" representation (4-bit exponent, 6-bit mantessa) "srn".
+ */
+static int
+fmult(
+ int an,
+ int srn)
+{
+ short anmag, anexp, anmant;
+ short wanexp, wanmant;
+ short retval;
+
+ anmag = (an > 0) ? an : ((-an) & 0x1FFF);
+ anexp = quan(anmag, power2, 15) - 6;
+ anmant = (anmag == 0) ? 32 :
+ (anexp >= 0) ? anmag >> anexp : anmag << -anexp;
+ wanexp = anexp + ((srn >> 6) & 0xF) - 13;
+
+ wanmant = (anmant * (srn & 077) + 0x30) >> 4;
+ retval = (wanexp >= 0) ? ((wanmant << wanexp) & 0x7FFF) :
+ (wanmant >> -wanexp);
+
+ return (((an ^ srn) < 0) ? -retval : retval);
+}
+
+/*
+ * g72x_init_state()
+ *
+ * This routine initializes and/or resets the g72x_state structure
+ * pointed to by 'state_ptr'.
+ * All the initial state values are specified in the CCITT G.721 document.
+ */
+void
+g72x_init_state(
+ struct g72x_state *state_ptr)
+{
+ int cnta;
+
+ state_ptr->yl = 34816;
+ state_ptr->yu = 544;
+ state_ptr->dms = 0;
+ state_ptr->dml = 0;
+ state_ptr->ap = 0;
+ for (cnta = 0; cnta < 2; cnta++) {
+ state_ptr->a[cnta] = 0;
+ state_ptr->pk[cnta] = 0;
+ state_ptr->sr[cnta] = 32;
+ }
+ for (cnta = 0; cnta < 6; cnta++) {
+ state_ptr->b[cnta] = 0;
+ state_ptr->dq[cnta] = 32;
+ }
+ state_ptr->td = 0;
+}
+
+/*
+ * predictor_zero()
+ *
+ * computes the estimated signal from 6-zero predictor.
+ *
+ */
+int
+predictor_zero(
+ struct g72x_state *state_ptr)
+{
+ int i;
+ int sezi;
+
+ sezi = fmult(state_ptr->b[0] >> 2, state_ptr->dq[0]);
+ for (i = 1; i < 6; i++) /* ACCUM */
+ sezi += fmult(state_ptr->b[i] >> 2, state_ptr->dq[i]);
+ return (sezi);
+}
+/*
+ * predictor_pole()
+ *
+ * computes the estimated signal from 2-pole predictor.
+ *
+ */
+int
+predictor_pole(
+ struct g72x_state *state_ptr)
+{
+ return (fmult(state_ptr->a[1] >> 2, state_ptr->sr[1]) +
+ fmult(state_ptr->a[0] >> 2, state_ptr->sr[0]));
+}
+/*
+ * step_size()
+ *
+ * computes the quantization step size of the adaptive quantizer.
+ *
+ */
+int
+step_size(
+ struct g72x_state *state_ptr)
+{
+ int y;
+ int dif;
+ int al;
+
+ if (state_ptr->ap >= 256)
+ return (state_ptr->yu);
+ else {
+ y = state_ptr->yl >> 6;
+ dif = state_ptr->yu - y;
+ al = state_ptr->ap >> 2;
+ if (dif > 0)
+ y += (dif * al) >> 6;
+ else if (dif < 0)
+ y += (dif * al + 0x3F) >> 6;
+ return (y);
+ }
+}
+
+/*
+ * quantize()
+ *
+ * Given a raw sample, 'd', of the difference signal and a
+ * quantization step size scale factor, 'y', this routine returns the
+ * ADPCM codeword to which that sample gets quantized. The step
+ * size scale factor division operation is done in the log base 2 domain
+ * as a subtraction.
+ */
+int
+quantize(
+ int d, /* Raw difference signal sample */
+ int y, /* Step size multiplier */
+ short *table, /* quantization table */
+ int size) /* table size of short integers */
+{
+ short dqm; /* Magnitude of 'd' */
+ short exp; /* Integer part of base 2 log of 'd' */
+ short mant; /* Fractional part of base 2 log */
+ short dl; /* Log of magnitude of 'd' */
+ short dln; /* Step size scale factor normalized log */
+ int i;
+
+ /*
+ * LOG
+ *
+ * Compute base 2 log of 'd', and store in 'dl'.
+ */
+ dqm = abs(d);
+ exp = quan(dqm >> 1, power2, 15);
+ mant = ((dqm << 7) >> exp) & 0x7F; /* Fractional portion. */
+ dl = (exp << 7) + mant;
+
+ /*
+ * SUBTB
+ *
+ * "Divide" by step size multiplier.
+ */
+ dln = dl - (y >> 2);
+
+ /*
+ * QUAN
+ *
+ * Obtain codword i for 'd'.
+ */
+ i = quan(dln, table, size);
+ if (d < 0) /* take 1's complement of i */
+ return ((size << 1) + 1 - i);
+ else if (i == 0) /* take 1's complement of 0 */
+ return ((size << 1) + 1); /* new in 1988 */
+ else
+ return (i);
+}
+/*
+ * reconstruct()
+ *
+ * Returns reconstructed difference signal 'dq' obtained from
+ * codeword 'i' and quantization step size scale factor 'y'.
+ * Multiplication is performed in log base 2 domain as addition.
+ */
+int
+reconstruct(
+ int sign, /* 0 for non-negative value */
+ int dqln, /* G.72x codeword */
+ int y) /* Step size multiplier */
+{
+ short dql; /* Log of 'dq' magnitude */
+ short dex; /* Integer part of log */
+ short dqt;
+ short dq; /* Reconstructed difference signal sample */
+
+ dql = dqln + (y >> 2); /* ADDA */
+
+ if (dql < 0) {
+ return ((sign) ? -0x8000 : 0);
+ } else { /* ANTILOG */
+ dex = (dql >> 7) & 15;
+ dqt = 128 + (dql & 127);
+ dq = (dqt << 7) >> (14 - dex);
+ return ((sign) ? (dq - 0x8000) : dq);
+ }
+}
+
+
+/*
+ * update()
+ *
+ * updates the state variables for each output code
+ */
+void
+update(
+ int code_size, /* distinguish 723_40 with others */
+ int y, /* quantizer step size */
+ int wi, /* scale factor multiplier */
+ int fi, /* for long/short term energies */
+ int dq, /* quantized prediction difference */
+ int sr, /* reconstructed signal */
+ int dqsez, /* difference from 2-pole predictor */
+ struct g72x_state *state_ptr) /* coder state pointer */
+{
+ int cnt;
+ short mag, exp; /* Adaptive predictor, FLOAT A */
+ short a2p = 0; /* LIMC */
+ short a1ul; /* UPA1 */
+ short pks1; /* UPA2 */
+ short fa1;
+ char tr; /* tone/transition detector */
+ short ylint, thr2, dqthr;
+ short ylfrac, thr1;
+ short pk0;
+
+ pk0 = (dqsez < 0) ? 1 : 0; /* needed in updating predictor poles */
+
+ mag = dq & 0x7FFF; /* prediction difference magnitude */
+ /* TRANS */
+ ylint = state_ptr->yl >> 15; /* exponent part of yl */
+ ylfrac = (state_ptr->yl >> 10) & 0x1F; /* fractional part of yl */
+ thr1 = (32 + ylfrac) << ylint; /* threshold */
+ thr2 = (ylint > 9) ? 31 << 10 : thr1; /* limit thr2 to 31 << 10 */
+ dqthr = (thr2 + (thr2 >> 1)) >> 1; /* dqthr = 0.75 * thr2 */
+ if (state_ptr->td == 0) /* signal supposed voice */
+ tr = 0;
+ else if (mag <= dqthr) /* supposed data, but small mag */
+ tr = 0; /* treated as voice */
+ else /* signal is data (modem) */
+ tr = 1;
+
+ /*
+ * Quantizer scale factor adaptation.
+ */
+
+ /* FUNCTW & FILTD & DELAY */
+ /* update non-steady state step size multiplier */
+ state_ptr->yu = y + ((wi - y) >> 5);
+
+ /* LIMB */
+ if (state_ptr->yu < 544) /* 544 <= yu <= 5120 */
+ state_ptr->yu = 544;
+ else if (state_ptr->yu > 5120)
+ state_ptr->yu = 5120;
+
+ /* FILTE & DELAY */
+ /* update steady state step size multiplier */
+ state_ptr->yl += state_ptr->yu + ((-state_ptr->yl) >> 6);
+
+ /*
+ * Adaptive predictor coefficients.
+ */
+ if (tr == 1) { /* reset a's and b's for modem signal */
+ state_ptr->a[0] = 0;
+ state_ptr->a[1] = 0;
+ state_ptr->b[0] = 0;
+ state_ptr->b[1] = 0;
+ state_ptr->b[2] = 0;
+ state_ptr->b[3] = 0;
+ state_ptr->b[4] = 0;
+ state_ptr->b[5] = 0;
+ } else { /* update a's and b's */
+ pks1 = pk0 ^ state_ptr->pk[0]; /* UPA2 */
+
+ /* update predictor pole a[1] */
+ a2p = state_ptr->a[1] - (state_ptr->a[1] >> 7);
+ if (dqsez != 0) {
+ fa1 = (pks1) ? state_ptr->a[0] : -state_ptr->a[0];
+ if (fa1 < -8191) /* a2p = function of fa1 */
+ a2p -= 0x100;
+ else if (fa1 > 8191)
+ a2p += 0xFF;
+ else
+ a2p += fa1 >> 5;
+
+ if (pk0 ^ state_ptr->pk[1])
+ /* LIMC */
+ if (a2p <= -12160)
+ a2p = -12288;
+ else if (a2p >= 12416)
+ a2p = 12288;
+ else
+ a2p -= 0x80;
+ else if (a2p <= -12416)
+ a2p = -12288;
+ else if (a2p >= 12160)
+ a2p = 12288;
+ else
+ a2p += 0x80;
+ }
+
+ /* TRIGB & DELAY */
+ state_ptr->a[1] = a2p;
+
+ /* UPA1 */
+ /* update predictor pole a[0] */
+ state_ptr->a[0] -= state_ptr->a[0] >> 8;
+ if (dqsez != 0){
+ if (pks1 == 0)
+ state_ptr->a[0] += 192;
+ else
+ state_ptr->a[0] -= 192;
+ }
+
+ /* LIMD */
+ a1ul = 15360 - a2p;
+ if (state_ptr->a[0] < -a1ul)
+ state_ptr->a[0] = -a1ul;
+ else if (state_ptr->a[0] > a1ul)
+ state_ptr->a[0] = a1ul;
+
+ /* UPB : update predictor zeros b[6] */
+ for (cnt = 0; cnt < 6; cnt++) {
+ if (code_size == 5) /* for 40Kbps G.723 */
+ state_ptr->b[cnt] -= state_ptr->b[cnt] >> 9;
+ else /* for G.721 and 24Kbps G.723 */
+ state_ptr->b[cnt] -= state_ptr->b[cnt] >> 8;
+ if (dq & 0x7FFF) { /* XOR */
+ if ((dq ^ state_ptr->dq[cnt]) >= 0)
+ state_ptr->b[cnt] += 128;
+ else
+ state_ptr->b[cnt] -= 128;
+ }
+ }
+ }
+
+ for (cnt = 5; cnt > 0; cnt--)
+ state_ptr->dq[cnt] = state_ptr->dq[cnt-1];
+ /* FLOAT A : convert dq[0] to 4-bit exp, 6-bit mantissa f.p. */
+ if (mag == 0) {
+ state_ptr->dq[0] = (dq >= 0) ? 0x20 : 0xFC20;
+ } else {
+ exp = quan(mag, power2, 15);
+ state_ptr->dq[0] = (dq >= 0) ?
+ (exp << 6) + ((mag << 6) >> exp) :
+ (exp << 6) + ((mag << 6) >> exp) - 0x400;
+ }
+
+ state_ptr->sr[1] = state_ptr->sr[0];
+ /* FLOAT B : convert sr to 4-bit exp., 6-bit mantissa f.p. */
+ if (sr == 0) {
+ state_ptr->sr[0] = 0x20;
+ } else if (sr > 0) {
+ exp = quan(sr, power2, 15);
+ state_ptr->sr[0] = (exp << 6) + ((sr << 6) >> exp);
+ } else if (sr > -32768) {
+ mag = -sr;
+ exp = quan(mag, power2, 15);
+ state_ptr->sr[0] = (exp << 6) + ((mag << 6) >> exp) - 0x400;
+ } else
+ state_ptr->sr[0] = 0xFC20;
+
+ /* DELAY A */
+ state_ptr->pk[1] = state_ptr->pk[0];
+ state_ptr->pk[0] = pk0;
+
+ /* TONE */
+ if (tr == 1) /* this sample has been treated as data */
+ state_ptr->td = 0; /* next one will be treated as voice */
+ else if (a2p < -11776) /* small sample-to-sample correlation */
+ state_ptr->td = 1; /* signal may be data */
+ else /* signal is voice */
+ state_ptr->td = 0;
+
+ /*
+ * Adaptation speed control.
+ */
+ state_ptr->dms += (fi - state_ptr->dms) >> 5; /* FILTA */
+ state_ptr->dml += (((fi << 2) - state_ptr->dml) >> 7); /* FILTB */
+
+ if (tr == 1)
+ state_ptr->ap = 256;
+ else if (y < 1536) /* SUBTC */
+ state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
+ else if (state_ptr->td == 1)
+ state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
+ else if (abs((state_ptr->dms << 2) - state_ptr->dml) >=
+ (state_ptr->dml >> 3))
+ state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
+ else
+ state_ptr->ap += (-state_ptr->ap) >> 4;
+}
+
+/*
+ * tandem_adjust(sr, se, y, i, sign)
+ *
+ * At the end of ADPCM decoding, it simulates an encoder which may be receiving
+ * the output of this decoder as a tandem process. If the output of the
+ * simulated encoder differs from the input to this decoder, the decoder output
+ * is adjusted by one level of A-law or u-law codes.
+ *
+ * Input:
+ * sr decoder output linear PCM sample,
+ * se predictor estimate sample,
+ * y quantizer step size,
+ * i decoder input code,
+ * sign sign bit of code i
+ *
+ * Return:
+ * adjusted A-law or u-law compressed sample.
+ */
+int
+tandem_adjust_alaw(
+ int sr, /* decoder output linear PCM sample */
+ int se, /* predictor estimate sample */
+ int y, /* quantizer step size */
+ int i, /* decoder input code */
+ int sign,
+ short *qtab)
+{
+ unsigned char sp; /* A-law compressed 8-bit code */
+ short dx; /* prediction error */
+ char id; /* quantized prediction error */
+ int sd; /* adjusted A-law decoded sample value */
+ int im; /* biased magnitude of i */
+ int imx; /* biased magnitude of id */
+
+ if (sr <= -32768)
+ sr = -1;
+ sp = linear2alaw((sr >> 1) << 3); /* short to A-law compression */
+ dx = (alaw2linear(sp) >> 2) - se; /* 16-bit prediction error */
+ id = quantize(dx, y, qtab, sign - 1);
+
+ if (id == i) { /* no adjustment on sp */
+ return (sp);
+ } else { /* sp adjustment needed */
+ /* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */
+ im = i ^ sign; /* 2's complement to biased unsigned */
+ imx = id ^ sign;
+
+ if (imx > im) { /* sp adjusted to next lower value */
+ if (sp & 0x80) {
+ sd = (sp == 0xD5) ? 0x55 :
+ ((sp ^ 0x55) - 1) ^ 0x55;
+ } else {
+ sd = (sp == 0x2A) ? 0x2A :
+ ((sp ^ 0x55) + 1) ^ 0x55;
+ }
+ } else { /* sp adjusted to next higher value */
+ if (sp & 0x80)
+ sd = (sp == 0xAA) ? 0xAA :
+ ((sp ^ 0x55) + 1) ^ 0x55;
+ else
+ sd = (sp == 0x55) ? 0xD5 :
+ ((sp ^ 0x55) - 1) ^ 0x55;
+ }
+ return (sd);
+ }
+}
+
+int
+tandem_adjust_ulaw(
+ int sr, /* decoder output linear PCM sample */
+ int se, /* predictor estimate sample */
+ int y, /* quantizer step size */
+ int i, /* decoder input code */
+ int sign,
+ short *qtab)
+{
+ unsigned char sp; /* u-law compressed 8-bit code */
+ short dx; /* prediction error */
+ char id; /* quantized prediction error */
+ int sd; /* adjusted u-law decoded sample value */
+ int im; /* biased magnitude of i */
+ int imx; /* biased magnitude of id */
+
+ if (sr <= -32768)
+ sr = 0;
+ sp = linear2ulaw(sr << 2); /* short to u-law compression */
+ dx = (ulaw2linear(sp) >> 2) - se; /* 16-bit prediction error */
+ id = quantize(dx, y, qtab, sign - 1);
+ if (id == i) {
+ return (sp);
+ } else {
+ /* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */
+ im = i ^ sign; /* 2's complement to biased unsigned */
+ imx = id ^ sign;
+ if (imx > im) { /* sp adjusted to next lower value */
+ if (sp & 0x80)
+ sd = (sp == 0xFF) ? 0x7E : sp + 1;
+ else
+ sd = (sp == 0) ? 0 : sp - 1;
+
+ } else { /* sp adjusted to next higher value */
+ if (sp & 0x80)
+ sd = (sp == 0x80) ? 0x80 : sp - 1;
+ else
+ sd = (sp == 0x7F) ? 0xFE : sp + 1;
+ }
+ return (sd);
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gnuradio-core/src/lib/g72x/g72x.h b/gnuradio-core/src/lib/g72x/g72x.h
new file mode 100644
index 0000000000..33807171aa
--- /dev/null
+++ b/gnuradio-core/src/lib/g72x/g72x.h
@@ -0,0 +1,156 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use. Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * g72x.h
+ *
+ * Header file for CCITT conversion routines.
+ *
+ */
+#ifndef _G72X_H
+#define _G72X_H
+
+#define AUDIO_ENCODING_ULAW (1) /* ISDN u-law */
+#define AUDIO_ENCODING_ALAW (2) /* ISDN A-law */
+#define AUDIO_ENCODING_LINEAR (3) /* PCM 2's-complement (0-center) */
+
+/*
+ * The following is the definition of the state structure
+ * used by the G.721/G.723 encoder and decoder to preserve their internal
+ * state between successive calls. The meanings of the majority
+ * of the state structure fields are explained in detail in the
+ * CCITT Recommendation G.721. The field names are essentially indentical
+ * to variable names in the bit level description of the coding algorithm
+ * included in this Recommendation.
+ */
+struct g72x_state {
+ long yl; /* Locked or steady state step size multiplier. */
+ short yu; /* Unlocked or non-steady state step size multiplier. */
+ short dms; /* Short term energy estimate. */
+ short dml; /* Long term energy estimate. */
+ short ap; /* Linear weighting coefficient of 'yl' and 'yu'. */
+
+ short a[2]; /* Coefficients of pole portion of prediction filter. */
+ short b[6]; /* Coefficients of zero portion of prediction filter. */
+ short pk[2]; /*
+ * Signs of previous two samples of a partially
+ * reconstructed signal.
+ */
+ short dq[6]; /*
+ * Previous 6 samples of the quantized difference
+ * signal represented in an internal floating point
+ * format.
+ */
+ short sr[2]; /*
+ * Previous 2 samples of the quantized difference
+ * signal represented in an internal floating point
+ * format.
+ */
+ char td; /* delayed tone detect, new in 1988 version */
+};
+
+/* External function definitions. */
+
+extern void g72x_init_state(struct g72x_state *);
+extern int g721_encoder(
+ int sample,
+ int in_coding,
+ struct g72x_state *state_ptr);
+extern int g721_decoder(
+ int code,
+ int out_coding,
+ struct g72x_state *state_ptr);
+extern int g723_24_encoder(
+ int sample,
+ int in_coding,
+ struct g72x_state *state_ptr);
+extern int g723_24_decoder(
+ int code,
+ int out_coding,
+ struct g72x_state *state_ptr);
+extern int g723_40_encoder(
+ int sample,
+ int in_coding,
+ struct g72x_state *state_ptr);
+extern int g723_40_decoder(
+ int code,
+ int out_coding,
+ struct g72x_state *state_ptr);
+
+
+extern int
+quantize(
+ int d,
+ int y,
+ short *table,
+ int size);
+extern int reconstruct(int,int,int);void
+
+extern update(
+ int code_size,
+ int y,
+ int wi,
+ int fi,
+ int dq,
+ int sr,
+ int dqsez,
+ struct g72x_state *state_ptr);
+extern int
+tandem_adjust_alaw(
+ int sr,
+ int se,
+ int y,
+ int i,
+ int sign,
+ short *qtab);
+
+extern int
+tandem_adjust_ulaw(
+ int sr,
+ int se,
+ int y,
+ int i,
+ int sign,
+ short *qtab);
+
+extern unsigned char
+linear2alaw(
+ int pcm_val);
+
+extern int
+alaw2linear(
+ unsigned char a_val);
+
+extern unsigned char
+linear2ulaw(int pcm_val);
+
+extern int ulaw2linear( unsigned char u_val);
+
+extern int predictor_zero(struct g72x_state *state_ptr);
+
+extern int predictor_pole( struct g72x_state *state_ptr);
+extern int step_size( struct g72x_state *state_ptr);
+#endif /* !_G72X_H */
diff --git a/gnuradio-core/src/lib/general/Makefile.am b/gnuradio-core/src/lib/general/Makefile.am
new file mode 100644
index 0000000000..a240cc9175
--- /dev/null
+++ b/gnuradio-core/src/lib/general/Makefile.am
@@ -0,0 +1,440 @@
+#
+# Copyright 2001,2002,2004,2006 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+include $(top_srcdir)/Makefile.common
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(CPPUNIT_INCLUDES)
+
+noinst_LTLIBRARIES = libgeneral.la libgeneral-qa.la
+
+# ----------------------------------------------------------------
+# these scripts generate code
+
+CODE_GENERATOR = \
+ generate_all.py \
+ generate_common.py \
+ gr_add_XX.cc.t \
+ gr_add_XX.h.t \
+ gr_add_XX.i.t \
+ gr_add_const_XX.cc.t \
+ gr_add_const_XX.h.t \
+ gr_add_const_XX.i.t \
+ gr_chunks_to_symbols_XX.cc.t \
+ gr_chunks_to_symbols_XX.h.t \
+ gr_chunks_to_symbols_XX.i.t \
+ gr_divide_XX.cc.t \
+ gr_divide_XX.h.t \
+ gr_divide_XX.i.t \
+ gr_multiply_XX.cc.t \
+ gr_multiply_XX.h.t \
+ gr_multiply_XX.i.t \
+ gr_multiply_const_XX.cc.t \
+ gr_multiply_const_XX.h.t \
+ gr_multiply_const_XX.i.t \
+ gr_mute_XX.cc.t \
+ gr_mute_XX.h.t \
+ gr_mute_XX.i.t \
+ gr_noise_source_X.cc.t \
+ gr_noise_source_X.h.t \
+ gr_noise_source_X.i.t \
+ gr_packed_to_unpacked_XX.cc.t \
+ gr_packed_to_unpacked_XX.h.t \
+ gr_packed_to_unpacked_XX.i.t \
+ gr_sig_source_X.cc.t \
+ gr_sig_source_X.h.t \
+ gr_sig_source_X.i.t \
+ gr_sub_XX.cc.t \
+ gr_sub_XX.h.t \
+ gr_sub_XX.i.t \
+ gr_unpacked_to_packed_XX.cc.t \
+ gr_unpacked_to_packed_XX.h.t \
+ gr_unpacked_to_packed_XX.i.t \
+ gr_vector_source_X.cc.t \
+ gr_vector_source_X.h.t \
+ gr_vector_source_X.i.t \
+ gr_vector_sink_X.cc.t \
+ gr_vector_sink_X.h.t \
+ gr_vector_sink_X.i.t
+
+# include $(srcdir)/Makefile.gen
+include Makefile.gen
+
+
+$(GENERATED_H) $(GENERATED_I) $(GENERATED_CC): $(CODE_GENERATOR)
+ PYTHONPATH=$(top_srcdir)/gnuradio-core/src/python srcdir=$(srcdir) $(srcdir)/generate_all.py
+
+
+BUILT_SOURCES = $(GENERATED_H) $(GENERATED_I) $(GENERATED_CC)
+
+# ----------------------------------------------------------------
+
+EXTRA_DIST = \
+ $(CODE_GENERATOR) \
+ gen_sine_table.py \
+ gr_prefix.cc.in
+
+libgeneral_la_SOURCES = \
+ $(GENERATED_CC) \
+ gr_agc_cc.cc \
+ gr_agc_ff.cc \
+ gr_align_on_samplenumbers_ss.cc \
+ gr_binary_slicer_fb.cc \
+ gr_bytes_to_syms.cc \
+ gr_char_to_float.cc \
+ gr_check_counting_s.cc \
+ gr_check_lfsr_32k_s.cc \
+ gr_circular_file.cc \
+ gr_clock_recovery_mm_cc.cc \
+ gr_clock_recovery_mm_ff.cc \
+ gr_complex_to_interleaved_short.cc \
+ gr_complex_to_xxx.cc \
+ gr_conjugate_cc.cc \
+ gr_constellation_decoder_cb.cc \
+ gr_correlate_access_code_bb.cc \
+ gr_costas_loop_cc.cc \
+ gr_count_bits.cc \
+ gr_crc32.cc \
+ gr_ctcss_squelch_ff.cc \
+ gr_dd_mpsk_sync_cc.cc \
+ gr_deinterleave.cc \
+ gr_diff_decoder_bb.cc \
+ gr_diff_encoder_bb.cc \
+ gr_diff_phasor_cc.cc \
+ gr_fake_channel_coder_pp.cc \
+ gr_fast_atan2f.cc \
+ gr_feval.cc \
+ gr_fft_vcc.cc \
+ gr_fft_vfc.cc \
+ gr_firdes.cc \
+ gr_float_to_char.cc \
+ gr_float_to_complex.cc \
+ gr_float_to_short.cc \
+ gr_float_to_uchar.cc \
+ gr_frequency_modulator_fc.cc \
+ gr_fxpt.cc \
+ gr_framer_sink_1.cc \
+ gr_head.cc \
+ gr_interleave.cc \
+ gr_interleaved_short_to_complex.cc \
+ gr_keep_one_in_n.cc \
+ gr_kludge_copy.cc \
+ gr_lfsr_32k_source_s.cc \
+ gr_lms_dfe_cc.cc \
+ gr_lms_dfe_ff.cc \
+ gr_map_bb.cc \
+ gr_math.cc \
+ gr_misc.cc \
+ gr_nlog10_ff.cc \
+ gr_nop.cc \
+ gr_null_sink.cc \
+ gr_null_source.cc \
+ gr_pa_2x2_phase_combiner.cc \
+ gr_packet_sink.cc \
+ gr_phase_modulator_fc.cc \
+ gr_pll_carriertracking_cc.cc \
+ gr_pll_freqdet_cf.cc \
+ gr_pll_refout_cc.cc \
+ gr_prefix.cc \
+ gr_prefs.cc \
+ gr_probe_avg_mag_sqrd_c.cc \
+ gr_probe_avg_mag_sqrd_f.cc \
+ gr_probe_signal_f.cc \
+ gr_pwr_squelch_cc.cc \
+ gr_pwr_squelch_ff.cc \
+ gr_quadrature_demod_cf.cc \
+ gr_random.cc \
+ gr_remez.cc \
+ gr_reverse.cc \
+ gr_rms_cf.cc \
+ gr_rms_ff.cc \
+ gr_short_to_float.cc \
+ gr_simple_correlator.cc \
+ gr_simple_framer.cc \
+ gr_simple_squelch_cc.cc \
+ gr_skiphead.cc \
+ gr_squelch_base_cc.cc \
+ gr_squelch_base_ff.cc \
+ gr_stream_to_streams.cc \
+ gr_stream_to_vector.cc \
+ gr_streams_to_stream.cc \
+ gr_streams_to_vector.cc \
+ gr_sync_block.cc \
+ gr_sync_decimator.cc \
+ gr_sync_interpolator.cc \
+ gr_test.cc \
+ gr_threshold_ff.cc \
+ gr_throttle.cc \
+ gr_uchar_to_float.cc \
+ gr_vco_f.cc \
+ gr_vector_to_stream.cc \
+ gr_vector_to_streams.cc \
+ gri_add_const_ss_generic.cc \
+ gri_char_to_float.cc \
+ gri_debugger_hook.cc \
+ gri_fft.cc \
+ gri_float_to_char.cc \
+ gri_float_to_short.cc \
+ gri_float_to_uchar.cc \
+ gri_interleaved_short_to_complex.cc \
+ gri_short_to_float.cc \
+ gri_uchar_to_float.cc \
+ malloc16.c \
+ gr_unpack_k_bits_bb.cc
+
+libgeneral_qa_la_SOURCES = \
+ qa_general.cc \
+ qa_gr_circular_file.cc \
+ qa_gr_firdes.cc \
+ qa_gr_fxpt.cc \
+ qa_gr_fxpt_nco.cc \
+ qa_gr_fxpt_vco.cc
+
+
+
+grinclude_HEADERS = \
+ $(GENERATED_H) \
+ gr_agc_cc.h \
+ gr_agc_ff.h \
+ gr_align_on_samplenumbers_ss.h \
+ gr_binary_slicer_fb.h \
+ gr_bytes_to_syms.h \
+ gr_char_to_float.h \
+ gr_check_counting_s.h \
+ gr_check_lfsr_32k_s.h \
+ gr_circular_file.h \
+ gr_clock_recovery_mm_cc.h \
+ gr_clock_recovery_mm_ff.h \
+ gr_complex_to_interleaved_short.h \
+ gr_complex_to_xxx.h \
+ gr_conjugate_cc.h \
+ gr_constellation_decoder_cb.h \
+ gr_correlate_access_code_bb.h \
+ gr_costas_loop_cc.h \
+ gr_count_bits.h \
+ gr_crc32.h \
+ gr_ctcss_squelch_ff.h \
+ gr_dd_mpsk_sync_cc.h \
+ gr_diff_decoder_bb.h \
+ gr_diff_encoder_bb.h \
+ gr_deinterleave.h \
+ gr_diff_phasor_cc.h \
+ gr_endianness.h \
+ gr_expj.h \
+ gr_fake_channel_coder_pp.h \
+ gr_feval.h \
+ gr_fft_vcc.h \
+ gr_fft_vfc.h \
+ gr_firdes.h \
+ gr_float_to_char.h \
+ gr_float_to_complex.h \
+ gr_float_to_short.h \
+ gr_float_to_uchar.h \
+ gr_framer_sink_1.h \
+ gr_frequency_modulator_fc.h \
+ gr_fxpt.h \
+ gr_fxpt_nco.h \
+ gr_fxpt_vco.h \
+ gr_head.h \
+ gr_interleave.h \
+ gr_interleaved_short_to_complex.h \
+ gr_keep_one_in_n.h \
+ gr_kludge_copy.h \
+ gr_lfsr_32k_source_s.h \
+ gr_lms_dfe_cc.h \
+ gr_lms_dfe_ff.h \
+ gr_log2_const.h \
+ gr_map_bb.h \
+ gr_math.h \
+ gr_misc.h \
+ gr_nco.h \
+ gr_nlog10_ff.h \
+ gr_noise_type.h \
+ gr_nop.h \
+ gr_null_sink.h \
+ gr_null_source.h \
+ gr_pa_2x2_phase_combiner.h \
+ gr_packet_sink.h \
+ gr_phase_modulator_fc.h \
+ gr_pll_carriertracking_cc.h \
+ gr_pll_freqdet_cf.h \
+ gr_pll_refout_cc.h \
+ gr_prefix.h \
+ gr_prefs.h \
+ gr_probe_avg_mag_sqrd_c.h \
+ gr_probe_avg_mag_sqrd_f.h \
+ gr_probe_signal_f.h \
+ gr_pwr_squelch_cc.h \
+ gr_pwr_squelch_ff.h \
+ gr_quadrature_demod_cf.h \
+ gr_random.h \
+ gr_remez.h \
+ gr_reverse.h \
+ gr_rms_cf.h \
+ gr_rms_ff.h \
+ gr_short_to_float.h \
+ gr_sig_source_waveform.h \
+ gr_simple_correlator.h \
+ gr_simple_framer.h \
+ gr_simple_framer_sync.h \
+ gr_simple_squelch_cc.h \
+ gr_skiphead.h \
+ gr_squelch_base_cc.h \
+ gr_squelch_base_ff.h \
+ gr_stream_to_streams.h \
+ gr_stream_to_vector.h \
+ gr_streams_to_stream.h \
+ gr_streams_to_vector.h \
+ gr_sync_block.h \
+ gr_sync_decimator.h \
+ gr_sync_interpolator.h \
+ gr_test_types.h \
+ gr_test.h \
+ gr_threshold_ff.h \
+ gr_throttle.h \
+ gr_uchar_to_float.h \
+ gr_vco.h \
+ gr_vco_f.h \
+ gr_vector_to_stream.h \
+ gr_vector_to_streams.h \
+ gri_add_const_ss.h \
+ gri_agc.h \
+ gri_agc_cc.h \
+ gri_char_to_float.h \
+ gri_debugger_hook.h \
+ gri_fft.h \
+ gri_float_to_char.h \
+ gri_float_to_short.h \
+ gri_float_to_uchar.h \
+ gri_interleaved_short_to_complex.h \
+ gri_lfsr_15_1_0.h \
+ gri_lfsr_32k.h \
+ gri_short_to_float.h \
+ gri_uchar_to_float.h \
+ malloc16.h \
+ random.h \
+ gr_unpack_k_bits_bb.h
+
+
+noinst_HEADERS = \
+ qa_general.h \
+ qa_gr_circular_file.h \
+ qa_gr_firdes.h \
+ qa_gr_fxpt.h \
+ qa_gr_fxpt_nco.h \
+ qa_gr_fxpt_vco.h \
+ sine_table.h
+
+swiginclude_HEADERS = \
+ $(GENERATED_I) \
+ general.i \
+ general_generated.i \
+ gr_agc_cc.i \
+ gr_agc_ff.i \
+ gr_align_on_samplenumbers_ss.i \
+ gr_binary_slicer_fb.i \
+ gr_bytes_to_syms.i \
+ gr_char_to_float.i \
+ gr_check_counting_s.i \
+ gr_check_lfsr_32k_s.i \
+ gr_clock_recovery_mm_cc.i \
+ gr_clock_recovery_mm_ff.i \
+ gr_complex_to_interleaved_short.i \
+ gr_complex_to_xxx.i \
+ gr_conjugate_cc.i \
+ gr_constellation_decoder_cb.i \
+ gr_correlate_access_code_bb.i \
+ gr_costas_loop_cc.i \
+ gr_crc32.i \
+ gr_ctcss_squelch_ff.i \
+ gr_dd_mpsk_sync_cc.i \
+ gr_diff_decoder_bb.i \
+ gr_diff_encoder_bb.i \
+ gr_diff_phasor_cc.i \
+ gr_deinterleave.i \
+ gr_endianness.i \
+ gr_fake_channel_coder_pp.i \
+ gr_feval.i \
+ gr_fft_vcc.i \
+ gr_fft_vfc.i \
+ gr_firdes.i \
+ gr_float_to_char.i \
+ gr_float_to_complex.i \
+ gr_float_to_short.i \
+ gr_float_to_uchar.i \
+ gr_frequency_modulator_fc.i \
+ gr_framer_sink_1.i \
+ gr_head.i \
+ gr_interleave.i \
+ gr_interleaved_short_to_complex.i \
+ gr_keep_one_in_n.i \
+ gr_kludge_copy.i \
+ gr_lfsr_32k_source_s.i \
+ gr_lms_dfe_cc.i \
+ gr_lms_dfe_ff.i \
+ gr_map_bb.i \
+ gr_nlog10_ff.i \
+ gr_nop.i \
+ gr_null_sink.i \
+ gr_null_source.i \
+ gr_pa_2x2_phase_combiner.i \
+ gr_packet_sink.i \
+ gr_phase_modulator_fc.i \
+ gr_pll_carriertracking_cc.i \
+ gr_pll_freqdet_cf.i \
+ gr_pll_refout_cc.i \
+ gr_prefix.i \
+ gr_prefs.i \
+ gr_probe_avg_mag_sqrd_c.i \
+ gr_probe_avg_mag_sqrd_f.i \
+ gr_probe_signal_f.i \
+ gr_pwr_squelch_cc.i \
+ gr_pwr_squelch_ff.i \
+ gr_quadrature_demod_cf.i \
+ gr_remez.i \
+ gr_rms_cf.i \
+ gr_rms_ff.i \
+ gr_short_to_float.i \
+ gr_simple_correlator.i \
+ gr_simple_framer.i \
+ gr_simple_squelch_cc.i \
+ gr_skiphead.i \
+ gr_squelch_base_cc.i \
+ gr_squelch_base_ff.i \
+ gr_stream_to_streams.i \
+ gr_stream_to_vector.i \
+ gr_streams_to_stream.i \
+ gr_streams_to_vector.i \
+ gr_sync_block.i \
+ gr_sync_decimator.i \
+ gr_sync_interpolator.i \
+ gr_test.i \
+ gr_threshold_ff.i \
+ gr_throttle.i \
+ gr_uchar_to_float.i \
+ gr_vco_f.i \
+ gr_vector_to_stream.i \
+ gr_vector_to_streams.i \
+ gri_agc.i \
+ gri_agc_cc.i \
+ gr_unpack_k_bits_bb.i
+
+
+CLEANFILES = $(BUILT_SOURCES) *.pyc
diff --git a/gnuradio-core/src/lib/general/Makefile.gen b/gnuradio-core/src/lib/general/Makefile.gen
new file mode 100644
index 0000000000..f0c477e3d0
--- /dev/null
+++ b/gnuradio-core/src/lib/general/Makefile.gen
@@ -0,0 +1,234 @@
+#
+# This file is machine generated. All edits will be overwritten
+#
+GENERATED_H = \
+ gr_add_cc.h \
+ gr_add_const_cc.h \
+ gr_add_const_ff.h \
+ gr_add_const_ii.h \
+ gr_add_const_sf.h \
+ gr_add_const_ss.h \
+ gr_add_const_vcc.h \
+ gr_add_const_vff.h \
+ gr_add_const_vii.h \
+ gr_add_const_vss.h \
+ gr_add_ff.h \
+ gr_add_ii.h \
+ gr_add_ss.h \
+ gr_add_vcc.h \
+ gr_add_vff.h \
+ gr_add_vii.h \
+ gr_add_vss.h \
+ gr_chunks_to_symbols_bc.h \
+ gr_chunks_to_symbols_bf.h \
+ gr_chunks_to_symbols_ic.h \
+ gr_chunks_to_symbols_if.h \
+ gr_chunks_to_symbols_sc.h \
+ gr_chunks_to_symbols_sf.h \
+ gr_divide_cc.h \
+ gr_divide_ff.h \
+ gr_divide_ii.h \
+ gr_divide_ss.h \
+ gr_multiply_cc.h \
+ gr_multiply_const_cc.h \
+ gr_multiply_const_ff.h \
+ gr_multiply_const_ii.h \
+ gr_multiply_const_ss.h \
+ gr_multiply_const_vcc.h \
+ gr_multiply_const_vff.h \
+ gr_multiply_const_vii.h \
+ gr_multiply_const_vss.h \
+ gr_multiply_ff.h \
+ gr_multiply_ii.h \
+ gr_multiply_ss.h \
+ gr_multiply_vcc.h \
+ gr_multiply_vff.h \
+ gr_multiply_vii.h \
+ gr_multiply_vss.h \
+ gr_mute_cc.h \
+ gr_mute_ff.h \
+ gr_mute_ii.h \
+ gr_mute_ss.h \
+ gr_noise_source_c.h \
+ gr_noise_source_f.h \
+ gr_noise_source_i.h \
+ gr_noise_source_s.h \
+ gr_packed_to_unpacked_bb.h \
+ gr_packed_to_unpacked_ii.h \
+ gr_packed_to_unpacked_ss.h \
+ gr_sig_source_c.h \
+ gr_sig_source_f.h \
+ gr_sig_source_i.h \
+ gr_sig_source_s.h \
+ gr_sub_cc.h \
+ gr_sub_ff.h \
+ gr_sub_ii.h \
+ gr_sub_ss.h \
+ gr_unpacked_to_packed_bb.h \
+ gr_unpacked_to_packed_ii.h \
+ gr_unpacked_to_packed_ss.h \
+ gr_vector_sink_b.h \
+ gr_vector_sink_c.h \
+ gr_vector_sink_f.h \
+ gr_vector_sink_i.h \
+ gr_vector_sink_s.h \
+ gr_vector_source_b.h \
+ gr_vector_source_c.h \
+ gr_vector_source_f.h \
+ gr_vector_source_i.h \
+ gr_vector_source_s.h
+
+GENERATED_I = \
+ gr_add_cc.i \
+ gr_add_const_cc.i \
+ gr_add_const_ff.i \
+ gr_add_const_ii.i \
+ gr_add_const_sf.i \
+ gr_add_const_ss.i \
+ gr_add_const_vcc.i \
+ gr_add_const_vff.i \
+ gr_add_const_vii.i \
+ gr_add_const_vss.i \
+ gr_add_ff.i \
+ gr_add_ii.i \
+ gr_add_ss.i \
+ gr_add_vcc.i \
+ gr_add_vff.i \
+ gr_add_vii.i \
+ gr_add_vss.i \
+ gr_chunks_to_symbols_bc.i \
+ gr_chunks_to_symbols_bf.i \
+ gr_chunks_to_symbols_ic.i \
+ gr_chunks_to_symbols_if.i \
+ gr_chunks_to_symbols_sc.i \
+ gr_chunks_to_symbols_sf.i \
+ gr_divide_cc.i \
+ gr_divide_ff.i \
+ gr_divide_ii.i \
+ gr_divide_ss.i \
+ gr_multiply_cc.i \
+ gr_multiply_const_cc.i \
+ gr_multiply_const_ff.i \
+ gr_multiply_const_ii.i \
+ gr_multiply_const_ss.i \
+ gr_multiply_const_vcc.i \
+ gr_multiply_const_vff.i \
+ gr_multiply_const_vii.i \
+ gr_multiply_const_vss.i \
+ gr_multiply_ff.i \
+ gr_multiply_ii.i \
+ gr_multiply_ss.i \
+ gr_multiply_vcc.i \
+ gr_multiply_vff.i \
+ gr_multiply_vii.i \
+ gr_multiply_vss.i \
+ gr_mute_cc.i \
+ gr_mute_ff.i \
+ gr_mute_ii.i \
+ gr_mute_ss.i \
+ gr_noise_source_c.i \
+ gr_noise_source_f.i \
+ gr_noise_source_i.i \
+ gr_noise_source_s.i \
+ gr_packed_to_unpacked_bb.i \
+ gr_packed_to_unpacked_ii.i \
+ gr_packed_to_unpacked_ss.i \
+ gr_sig_source_c.i \
+ gr_sig_source_f.i \
+ gr_sig_source_i.i \
+ gr_sig_source_s.i \
+ gr_sub_cc.i \
+ gr_sub_ff.i \
+ gr_sub_ii.i \
+ gr_sub_ss.i \
+ gr_unpacked_to_packed_bb.i \
+ gr_unpacked_to_packed_ii.i \
+ gr_unpacked_to_packed_ss.i \
+ gr_vector_sink_b.i \
+ gr_vector_sink_c.i \
+ gr_vector_sink_f.i \
+ gr_vector_sink_i.i \
+ gr_vector_sink_s.i \
+ gr_vector_source_b.i \
+ gr_vector_source_c.i \
+ gr_vector_source_f.i \
+ gr_vector_source_i.i \
+ gr_vector_source_s.i
+
+GENERATED_CC = \
+ gr_add_cc.cc \
+ gr_add_const_cc.cc \
+ gr_add_const_ff.cc \
+ gr_add_const_ii.cc \
+ gr_add_const_sf.cc \
+ gr_add_const_ss.cc \
+ gr_add_const_vcc.cc \
+ gr_add_const_vff.cc \
+ gr_add_const_vii.cc \
+ gr_add_const_vss.cc \
+ gr_add_ff.cc \
+ gr_add_ii.cc \
+ gr_add_ss.cc \
+ gr_add_vcc.cc \
+ gr_add_vff.cc \
+ gr_add_vii.cc \
+ gr_add_vss.cc \
+ gr_chunks_to_symbols_bc.cc \
+ gr_chunks_to_symbols_bf.cc \
+ gr_chunks_to_symbols_ic.cc \
+ gr_chunks_to_symbols_if.cc \
+ gr_chunks_to_symbols_sc.cc \
+ gr_chunks_to_symbols_sf.cc \
+ gr_divide_cc.cc \
+ gr_divide_ff.cc \
+ gr_divide_ii.cc \
+ gr_divide_ss.cc \
+ gr_multiply_cc.cc \
+ gr_multiply_const_cc.cc \
+ gr_multiply_const_ff.cc \
+ gr_multiply_const_ii.cc \
+ gr_multiply_const_ss.cc \
+ gr_multiply_const_vcc.cc \
+ gr_multiply_const_vff.cc \
+ gr_multiply_const_vii.cc \
+ gr_multiply_const_vss.cc \
+ gr_multiply_ff.cc \
+ gr_multiply_ii.cc \
+ gr_multiply_ss.cc \
+ gr_multiply_vcc.cc \
+ gr_multiply_vff.cc \
+ gr_multiply_vii.cc \
+ gr_multiply_vss.cc \
+ gr_mute_cc.cc \
+ gr_mute_ff.cc \
+ gr_mute_ii.cc \
+ gr_mute_ss.cc \
+ gr_noise_source_c.cc \
+ gr_noise_source_f.cc \
+ gr_noise_source_i.cc \
+ gr_noise_source_s.cc \
+ gr_packed_to_unpacked_bb.cc \
+ gr_packed_to_unpacked_ii.cc \
+ gr_packed_to_unpacked_ss.cc \
+ gr_sig_source_c.cc \
+ gr_sig_source_f.cc \
+ gr_sig_source_i.cc \
+ gr_sig_source_s.cc \
+ gr_sub_cc.cc \
+ gr_sub_ff.cc \
+ gr_sub_ii.cc \
+ gr_sub_ss.cc \
+ gr_unpacked_to_packed_bb.cc \
+ gr_unpacked_to_packed_ii.cc \
+ gr_unpacked_to_packed_ss.cc \
+ gr_vector_sink_b.cc \
+ gr_vector_sink_c.cc \
+ gr_vector_sink_f.cc \
+ gr_vector_sink_i.cc \
+ gr_vector_sink_s.cc \
+ gr_vector_source_b.cc \
+ gr_vector_source_c.cc \
+ gr_vector_source_f.cc \
+ gr_vector_source_i.cc \
+ gr_vector_source_s.cc
+
diff --git a/gnuradio-core/src/lib/general/README b/gnuradio-core/src/lib/general/README
new file mode 100644
index 0000000000..26d829f1be
--- /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 0000000000..3466412fb4
--- /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 0000000000..94445e96ec
--- /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 0000000000..ca7812cbfc
--- /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/gen_sine_table.py b/gnuradio-core/src/lib/general/gen_sine_table.py
new file mode 100755
index 0000000000..06a5e7c8ef
--- /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 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+import math
+import sys
+
+def wrap (x):
+ if x >= 2**31:
+ return x - 2**32
+ return x
+
+def gen_approx_table (f, nentries, min_x, max_x):
+ """return a list of nentries containing tuples of the form:
+ (m, c, abs_error). min_x and max_x specify the domain
+ of the table.
+ """
+ r = []
+ incx = float (max_x - min_x) / nentries
+ for i in range (nentries):
+ a = (i * incx) + min_x
+ b = ((i + 1) * incx) + min_x
+ m = (f(b)-f(a))/(b-a)
+ c = (3*a+b)*(f(a)-f(b))/(4*(b-a)) + (f((a+b)/2) + f(a))/2
+ abs_error = c+m*a-f(a)
+ r.append ((m, c, abs_error))
+ return r
+
+def scaled_sine (x):
+ return math.sin (x * math.pi / 2**31)
+
+def gen_sine_table ():
+ nbits = 10
+ nentries = 2**nbits
+
+ # min_x = -2**31
+ # max_x = 2**31-1
+ min_x = 0
+ max_x = 2**32-1
+ t = gen_approx_table (scaled_sine, nentries, min_x, max_x)
+
+ max_error = 0
+ for e in t:
+ max_error = max (max_error, abs (e[2]))
+
+ # sys.stdout.write ('static const int WORDBITS = 32;\n')
+ # sys.stdout.write ('static const int NBITS = %d;\n' % (nbits,))
+
+ sys.stdout.write (' // max_error = %22.15e\n' % (max_error,))
+
+ # sys.stdout.write ('static const double sine_table[%d][2] = {\n'% (nentries,))
+
+ for e in t:
+ sys.stdout.write (' { %22.15e, %22.15e },\n' % (2 * e[0], e[1]))
+
+ # sys.stdout.write ('};\n')
+
+if __name__ == '__main__':
+ gen_sine_table ()
diff --git a/gnuradio-core/src/lib/general/general.i b/gnuradio-core/src/lib/general/general.i
new file mode 100644
index 0000000000..3f410a9ead
--- /dev/null
+++ b/gnuradio-core/src/lib/general/general.i
@@ -0,0 +1,203 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+%{
+
+#include <gr_sync_block.h>
+#include <gr_sync_decimator.h>
+#include <gr_sync_interpolator.h>
+#include <gr_nop.h>
+#include <gr_null_sink.h>
+#include <gr_null_source.h>
+#include <gr_head.h>
+#include <gr_skiphead.h>
+#include <gr_sig_source_waveform.h>
+#include <gr_quadrature_demod_cf.h>
+#include <gr_remez.h>
+#include <gr_float_to_complex.h>
+#include <gr_check_counting_s.h>
+#include <gr_lfsr_32k_source_s.h>
+#include <gr_check_lfsr_32k_s.h>
+#include <gr_stream_to_vector.h>
+#include <gr_vector_to_stream.h>
+#include <gr_keep_one_in_n.h>
+#include <gr_fft_vcc.h>
+#include <gr_fft_vfc.h>
+#include <gr_float_to_short.h>
+#include <gr_float_to_char.h>
+#include <gr_float_to_uchar.h>
+#include <gr_short_to_float.h>
+#include <gr_char_to_float.h>
+#include <gr_uchar_to_float.h>
+#include <gr_frequency_modulator_fc.h>
+#include <gr_phase_modulator_fc.h>
+#include <gr_bytes_to_syms.h>
+#include <gr_simple_correlator.h>
+#include <gr_simple_framer.h>
+#include <gr_align_on_samplenumbers_ss.h>
+#include <gr_complex_to_xxx.h>
+#include <gr_complex_to_interleaved_short.h>
+#include <gr_interleaved_short_to_complex.h>
+#include <gr_endianness.h>
+#include <gr_firdes.h>
+#include <gr_interleave.h>
+#include <gr_deinterleave.h>
+#include <gr_simple_squelch_cc.h>
+#include <gr_agc_ff.h>
+#include <gr_agc_cc.h>
+#include <gr_rms_cf.h>
+#include <gr_rms_ff.h>
+#include <gr_nlog10_ff.h>
+#include <gr_fake_channel_coder_pp.h>
+#include <gr_throttle.h>
+#include <gr_stream_to_streams.h>
+#include <gr_streams_to_stream.h>
+#include <gr_streams_to_vector.h>
+#include <gr_vector_to_streams.h>
+#include <gr_conjugate_cc.h>
+#include <gr_vco_f.h>
+#include <gr_crc32.h>
+#include <gr_threshold_ff.h>
+#include <gr_clock_recovery_mm_ff.h>
+#include <gr_clock_recovery_mm_cc.h>
+#include <gr_dd_mpsk_sync_cc.h>
+#include <gr_packet_sink.h>
+#include <gr_lms_dfe_cc.h>
+#include <gr_lms_dfe_ff.h>
+#include <gr_pll_freqdet_cf.h>
+#include <gr_pll_refout_cc.h>
+#include <gr_pll_carriertracking_cc.h>
+#include <gr_probe_avg_mag_sqrd_c.h>
+#include <gr_probe_avg_mag_sqrd_f.h>
+#include <gr_probe_signal_f.h>
+#include <gr_costas_loop_cc.h>
+#include <gr_pa_2x2_phase_combiner.h>
+#include <gr_kludge_copy.h>
+#include <gr_prefs.h>
+#include <gr_prefix.h>
+#include <gr_test_types.h>
+#include <gr_test.h>
+#include <gr_unpack_k_bits_bb.h>
+#include <gr_correlate_access_code_bb.h>
+#include <gr_diff_phasor_cc.h>
+#include <gr_constellation_decoder_cb.h>
+#include <gr_binary_slicer_fb.h>
+#include <gr_diff_encoder_bb.h>
+#include <gr_diff_decoder_bb.h>
+#include <gr_framer_sink_1.h>
+#include <gr_map_bb.h>
+#include <gr_feval.h>
+#include <gr_pwr_squelch_cc.h>
+#include <gr_pwr_squelch_ff.h>
+#include <gr_ctcss_squelch_ff.h>
+%}
+
+%include "gr_sync_block.i"
+%include "gr_sync_decimator.i"
+%include "gr_sync_interpolator.i"
+%include "gr_nop.i"
+%include "gr_null_sink.i"
+%include "gr_null_source.i"
+%include "gr_head.i"
+%include "gr_skiphead.i"
+%include "gr_sig_source_waveform.h"
+%include "gr_noise_type.h"
+%include "gr_quadrature_demod_cf.i"
+%include "gr_remez.i"
+%include "gr_float_to_complex.i"
+%include "gr_check_counting_s.i"
+%include "gr_lfsr_32k_source_s.i"
+%include "gr_check_lfsr_32k_s.i"
+%include "gr_stream_to_vector.i"
+%include "gr_vector_to_stream.i"
+%include "gr_keep_one_in_n.i"
+%include "gr_fft_vcc.i"
+%include "gr_fft_vfc.i"
+%include "gr_float_to_short.i"
+%include "gr_float_to_char.i"
+%include "gr_float_to_uchar.i"
+%include "gr_short_to_float.i"
+%include "gr_char_to_float.i"
+%include "gr_uchar_to_float.i"
+%include "gr_frequency_modulator_fc.i"
+%include "gr_phase_modulator_fc.i"
+%include "gr_bytes_to_syms.i"
+%include "gr_simple_correlator.i"
+%include "gr_simple_framer.i"
+%include "gr_align_on_samplenumbers_ss.i"
+%include "gr_complex_to_xxx.i"
+%include "gr_complex_to_interleaved_short.i"
+%include "gr_endianness.i"
+%include "gr_interleaved_short_to_complex.i"
+%include "gr_firdes.i"
+%include "gr_interleave.i"
+%include "gr_deinterleave.i"
+%include "gr_simple_squelch_cc.i"
+%include "gr_agc_ff.i"
+%include "gr_agc_cc.i"
+%include "gr_rms_cf.i"
+%include "gr_rms_ff.i"
+%include "gr_nlog10_ff.i"
+%include "gr_fake_channel_coder_pp.i"
+%include "gr_throttle.i"
+%include "gr_stream_to_streams.i"
+%include "gr_streams_to_stream.i"
+%include "gr_streams_to_vector.i"
+%include "gr_vector_to_streams.i"
+%include "gr_conjugate_cc.i"
+%include "gr_vco_f.i"
+%include "gr_crc32.i"
+%include "gr_threshold_ff.i"
+%include "gr_clock_recovery_mm_ff.i"
+%include "gr_clock_recovery_mm_cc.i"
+%include "gr_dd_mpsk_sync_cc.i"
+%include "gr_packet_sink.i"
+%include "gr_lms_dfe_cc.i"
+%include "gr_lms_dfe_ff.i"
+%include "gr_pll_freqdet_cf.i"
+%include "gr_pll_refout_cc.i"
+%include "gr_pll_carriertracking_cc.i"
+%include "gr_probe_avg_mag_sqrd_c.i"
+%include "gr_probe_avg_mag_sqrd_f.i"
+%include "gr_probe_signal_f.i"
+%include "gr_costas_loop_cc.i"
+%include "gr_pa_2x2_phase_combiner.i"
+%include "gr_kludge_copy.i"
+%include "gr_prefs.i"
+%include "gr_prefix.i"
+%include "gr_test_types.h"
+%include "gr_test.i"
+%include "gr_unpack_k_bits_bb.i"
+%include "gr_correlate_access_code_bb.i"
+%include "gr_diff_phasor_cc.i"
+%include "gr_constellation_decoder_cb.i"
+%include "gr_binary_slicer_fb.i"
+%include "gr_diff_encoder_bb.i"
+%include "gr_diff_decoder_bb.i"
+%include "gr_framer_sink_1.i"
+%include "gr_map_bb.i"
+%include "gr_feval.i"
+%include "gr_pwr_squelch_cc.i"
+%include "gr_pwr_squelch_ff.i"
+%include "gr_ctcss_squelch_ff.i"
+
+%include "general_generated.i"
diff --git a/gnuradio-core/src/lib/general/general_generated.i b/gnuradio-core/src/lib/general/general_generated.i
new file mode 100644
index 0000000000..a41f30a3da
--- /dev/null
+++ b/gnuradio-core/src/lib/general/general_generated.i
@@ -0,0 +1,156 @@
+//
+// This file is machine generated. All edits will be overwritten
+//
+%{
+#include <gr_add_cc.h>
+#include <gr_add_const_cc.h>
+#include <gr_add_const_ff.h>
+#include <gr_add_const_ii.h>
+#include <gr_add_const_sf.h>
+#include <gr_add_const_ss.h>
+#include <gr_add_const_vcc.h>
+#include <gr_add_const_vff.h>
+#include <gr_add_const_vii.h>
+#include <gr_add_const_vss.h>
+#include <gr_add_ff.h>
+#include <gr_add_ii.h>
+#include <gr_add_ss.h>
+#include <gr_add_vcc.h>
+#include <gr_add_vff.h>
+#include <gr_add_vii.h>
+#include <gr_add_vss.h>
+#include <gr_chunks_to_symbols_bc.h>
+#include <gr_chunks_to_symbols_bf.h>
+#include <gr_chunks_to_symbols_ic.h>
+#include <gr_chunks_to_symbols_if.h>
+#include <gr_chunks_to_symbols_sc.h>
+#include <gr_chunks_to_symbols_sf.h>
+#include <gr_divide_cc.h>
+#include <gr_divide_ff.h>
+#include <gr_divide_ii.h>
+#include <gr_divide_ss.h>
+#include <gr_multiply_cc.h>
+#include <gr_multiply_const_cc.h>
+#include <gr_multiply_const_ff.h>
+#include <gr_multiply_const_ii.h>
+#include <gr_multiply_const_ss.h>
+#include <gr_multiply_const_vcc.h>
+#include <gr_multiply_const_vff.h>
+#include <gr_multiply_const_vii.h>
+#include <gr_multiply_const_vss.h>
+#include <gr_multiply_ff.h>
+#include <gr_multiply_ii.h>
+#include <gr_multiply_ss.h>
+#include <gr_multiply_vcc.h>
+#include <gr_multiply_vff.h>
+#include <gr_multiply_vii.h>
+#include <gr_multiply_vss.h>
+#include <gr_mute_cc.h>
+#include <gr_mute_ff.h>
+#include <gr_mute_ii.h>
+#include <gr_mute_ss.h>
+#include <gr_noise_source_c.h>
+#include <gr_noise_source_f.h>
+#include <gr_noise_source_i.h>
+#include <gr_noise_source_s.h>
+#include <gr_packed_to_unpacked_bb.h>
+#include <gr_packed_to_unpacked_ii.h>
+#include <gr_packed_to_unpacked_ss.h>
+#include <gr_sig_source_c.h>
+#include <gr_sig_source_f.h>
+#include <gr_sig_source_i.h>
+#include <gr_sig_source_s.h>
+#include <gr_sub_cc.h>
+#include <gr_sub_ff.h>
+#include <gr_sub_ii.h>
+#include <gr_sub_ss.h>
+#include <gr_unpacked_to_packed_bb.h>
+#include <gr_unpacked_to_packed_ii.h>
+#include <gr_unpacked_to_packed_ss.h>
+#include <gr_vector_sink_b.h>
+#include <gr_vector_sink_c.h>
+#include <gr_vector_sink_f.h>
+#include <gr_vector_sink_i.h>
+#include <gr_vector_sink_s.h>
+#include <gr_vector_source_b.h>
+#include <gr_vector_source_c.h>
+#include <gr_vector_source_f.h>
+#include <gr_vector_source_i.h>
+#include <gr_vector_source_s.h>
+%}
+
+%include <gr_add_cc.i>
+%include <gr_add_const_cc.i>
+%include <gr_add_const_ff.i>
+%include <gr_add_const_ii.i>
+%include <gr_add_const_sf.i>
+%include <gr_add_const_ss.i>
+%include <gr_add_const_vcc.i>
+%include <gr_add_const_vff.i>
+%include <gr_add_const_vii.i>
+%include <gr_add_const_vss.i>
+%include <gr_add_ff.i>
+%include <gr_add_ii.i>
+%include <gr_add_ss.i>
+%include <gr_add_vcc.i>
+%include <gr_add_vff.i>
+%include <gr_add_vii.i>
+%include <gr_add_vss.i>
+%include <gr_chunks_to_symbols_bc.i>
+%include <gr_chunks_to_symbols_bf.i>
+%include <gr_chunks_to_symbols_ic.i>
+%include <gr_chunks_to_symbols_if.i>
+%include <gr_chunks_to_symbols_sc.i>
+%include <gr_chunks_to_symbols_sf.i>
+%include <gr_divide_cc.i>
+%include <gr_divide_ff.i>
+%include <gr_divide_ii.i>
+%include <gr_divide_ss.i>
+%include <gr_multiply_cc.i>
+%include <gr_multiply_const_cc.i>
+%include <gr_multiply_const_ff.i>
+%include <gr_multiply_const_ii.i>
+%include <gr_multiply_const_ss.i>
+%include <gr_multiply_const_vcc.i>
+%include <gr_multiply_const_vff.i>
+%include <gr_multiply_const_vii.i>
+%include <gr_multiply_const_vss.i>
+%include <gr_multiply_ff.i>
+%include <gr_multiply_ii.i>
+%include <gr_multiply_ss.i>
+%include <gr_multiply_vcc.i>
+%include <gr_multiply_vff.i>
+%include <gr_multiply_vii.i>
+%include <gr_multiply_vss.i>
+%include <gr_mute_cc.i>
+%include <gr_mute_ff.i>
+%include <gr_mute_ii.i>
+%include <gr_mute_ss.i>
+%include <gr_noise_source_c.i>
+%include <gr_noise_source_f.i>
+%include <gr_noise_source_i.i>
+%include <gr_noise_source_s.i>
+%include <gr_packed_to_unpacked_bb.i>
+%include <gr_packed_to_unpacked_ii.i>
+%include <gr_packed_to_unpacked_ss.i>
+%include <gr_sig_source_c.i>
+%include <gr_sig_source_f.i>
+%include <gr_sig_source_i.i>
+%include <gr_sig_source_s.i>
+%include <gr_sub_cc.i>
+%include <gr_sub_ff.i>
+%include <gr_sub_ii.i>
+%include <gr_sub_ss.i>
+%include <gr_unpacked_to_packed_bb.i>
+%include <gr_unpacked_to_packed_ii.i>
+%include <gr_unpacked_to_packed_ss.i>
+%include <gr_vector_sink_b.i>
+%include <gr_vector_sink_c.i>
+%include <gr_vector_sink_f.i>
+%include <gr_vector_sink_i.i>
+%include <gr_vector_sink_s.i>
+%include <gr_vector_source_b.i>
+%include <gr_vector_source_c.i>
+%include <gr_vector_source_f.i>
+%include <gr_vector_source_i.i>
+%include <gr_vector_source_s.i>
diff --git a/gnuradio-core/src/lib/general/generate_all.py b/gnuradio-core/src/lib/general/generate_all.py
new file mode 100755
index 0000000000..1b33abb9ad
--- /dev/null
+++ b/gnuradio-core/src/lib/general/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 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+from build_utils import output_glue
+
+import generate_common
+
+def generate_all ():
+ generate_common.generate ()
+ output_glue ('general')
+
+
+if __name__ == '__main__':
+ generate_all ()
diff --git a/gnuradio-core/src/lib/general/generate_common.py b/gnuradio-core/src/lib/general/generate_common.py
new file mode 100755
index 0000000000..4616f4a979
--- /dev/null
+++ b/gnuradio-core/src/lib/general/generate_common.py
@@ -0,0 +1,93 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2006 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+from build_utils import expand_template, standard_dict
+from build_utils_codes import *
+
+import re
+
+
+# sources and sinks
+ss_signatures = ['s', 'i', 'f', 'c']
+
+ss_roots = [
+ 'gr_vector_source_X',
+ 'gr_vector_sink_X',
+ 'gr_noise_source_X',
+ 'gr_sig_source_X'
+ ]
+
+# regular blocks
+reg_signatures = ['ss', 'ii', 'ff', 'cc']
+
+reg_roots = [
+ 'gr_add_const_XX',
+ 'gr_multiply_const_XX',
+ 'gr_add_XX',
+ 'gr_sub_XX',
+ 'gr_multiply_XX',
+ 'gr_divide_XX',
+ 'gr_mute_XX',
+ 'gr_add_vXX',
+ 'gr_multiply_vXX',
+ 'gr_add_const_vXX',
+ 'gr_multiply_const_vXX'
+ ]
+
+# other blocks
+others = (
+ ('gr_chunks_to_symbols_XX', ('bf', 'bc', 'sf', 'sc', 'if', 'ic')),
+ ('gr_unpacked_to_packed_XX', ('bb','ss','ii')),
+ ('gr_packed_to_unpacked_XX', ('bb','ss','ii'))
+ )
+
+
+def expand_h_cc_i (root, sig):
+ # root looks like 'gr_vector_sink_X'
+ name = re.sub ('X+', sig, root)
+ d = standard_dict (name, sig)
+ expand_template (d, root + '.h.t')
+ expand_template (d, root + '.cc.t')
+ expand_template (d, root + '.i.t')
+
+
+def generate ():
+ expand_h_cc_i ('gr_add_const_XX', 'sf') # for MC4020
+ expand_h_cc_i ('gr_vector_sink_X', 'b')
+ expand_h_cc_i ('gr_vector_source_X', 'b')
+ for r in ss_roots:
+ for s in ss_signatures:
+ expand_h_cc_i (r, s)
+ for r in reg_roots :
+ for s in reg_signatures:
+ expand_h_cc_i (r, s)
+
+ for root, sigs in others:
+ for s in sigs:
+ expand_h_cc_i (root, s)
+
+
+
+if __name__ == '__main__':
+ generate ()
+
+
diff --git a/gnuradio-core/src/lib/general/gr_add_XX.cc.t b/gnuradio-core/src/lib/general/gr_add_XX.cc.t
new file mode 100644
index 0000000000..f743d87363
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_add_XX.cc.t
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ ()
+{
+ return @SPTR_NAME@ (new @NAME@ ());
+}
+
+@NAME@::@NAME@ ()
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (1, -1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@)))
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0];
+
+ int ninputs = input_items.size ();
+
+ for (int i = 0; i < noutput_items; i++){
+ @I_TYPE@ acc = ((@I_TYPE@ *) input_items[0])[i];
+ for (int j = 1; j < ninputs; j++)
+ acc += ((@I_TYPE@ *) input_items[j])[i];
+
+ *optr++ = (@O_TYPE@) acc;
+ }
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_add_XX.h.t b/gnuradio-core/src/lib/general/gr_add_XX.h.t
new file mode 100644
index 0000000000..1fa42e3627
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_add_XX.h.t
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+/*!
+ * \brief output = sum (input_0, input_1, ...)
+ * \ingroup block
+ *
+ * Add across all input streams.
+ */
+class @NAME@ : public gr_sync_block
+{
+ friend @SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+ @NAME@ ();
+
+ public:
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_add_XX.i.t b/gnuradio-core/src/lib/general/gr_add_XX.i.t
new file mode 100644
index 0000000000..8479aad683
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_add_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+ @NAME@ ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_add_const_XX.cc.t b/gnuradio-core/src/lib/general/gr_add_const_XX.cc.t
new file mode 100644
index 0000000000..1a2cf08db0
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_add_const_XX.cc.t
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (@O_TYPE@ k)
+{
+ return @SPTR_NAME@ (new @NAME@ (k));
+}
+
+@NAME@::@NAME@ (@O_TYPE@ k)
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@))),
+ d_k (k)
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ @I_TYPE@ *iptr = (@I_TYPE@ *) input_items[0];
+ @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0];
+
+ int size = noutput_items;
+
+ while (size >= 8){
+ *optr++ = *iptr++ + d_k;
+ *optr++ = *iptr++ + d_k;
+ *optr++ = *iptr++ + d_k;
+ *optr++ = *iptr++ + d_k;
+ *optr++ = *iptr++ + d_k;
+ *optr++ = *iptr++ + d_k;
+ *optr++ = *iptr++ + d_k;
+ *optr++ = *iptr++ + d_k;
+ size -= 8;
+ }
+
+ while (size-- > 0)
+ *optr++ = *iptr++ + d_k;
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_add_const_XX.h.t b/gnuradio-core/src/lib/general/gr_add_const_XX.h.t
new file mode 100644
index 0000000000..c965df3a1e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_add_const_XX.h.t
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (@O_TYPE@ k);
+
+/*!
+ * \brief output = input + constant
+ * \ingroup block
+ */
+class @NAME@ : public gr_sync_block
+{
+ friend @SPTR_NAME@ gr_make_@BASE_NAME@ (@O_TYPE@ k);
+
+ @O_TYPE@ d_k; // the constant
+ @NAME@ (@O_TYPE@ k);
+
+ public:
+ @O_TYPE@ k () const { return d_k; }
+ void set_k (@O_TYPE@ k) { d_k = k; }
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_add_const_XX.i.t b/gnuradio-core/src/lib/general/gr_add_const_XX.i.t
new file mode 100644
index 0000000000..c2c814b524
--- /dev/null
+++ b/gnuradio-core/src/lib/general/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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (@TYPE@ k);
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+ @NAME@ (@TYPE@ k);
+
+ public:
+ @TYPE@ k () const { return d_k; }
+ void set_k (@TYPE@ k) { d_k = k; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_add_const_vXX.cc.t b/gnuradio-core/src/lib/general/gr_add_const_vXX.cc.t
new file mode 100755
index 0000000000..7966331b10
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_add_const_vXX.cc.t
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k)
+{
+ return @SPTR_NAME@ (new @NAME@ (k));
+}
+
+@NAME@::@NAME@ (const std::vector<@I_TYPE@> k)
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof(@I_TYPE@)*k.size()),
+ gr_make_io_signature (1, 1, sizeof(@O_TYPE@)*k.size()))
+{
+ d_k = k;
+}
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ @I_TYPE@ *iptr = (@O_TYPE@ *)input_items[0];
+ @O_TYPE@ *optr = (@O_TYPE@ *)output_items[0];
+
+ int nitems_per_block = output_signature()->sizeof_stream_item(0)/sizeof(@I_TYPE@);
+
+ for (int i = 0; i < noutput_items; i++)
+ for (int j = 0; j < nitems_per_block; j++)
+ *optr++ = *iptr++ + d_k[j];
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_add_const_vXX.h.t b/gnuradio-core/src/lib/general/gr_add_const_vXX.h.t
new file mode 100755
index 0000000000..b42bc2d943
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_add_const_vXX.h.t
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k);
+
+/*!
+ * \brief output vector = input vector + constant vector
+ * \ingroup block
+ */
+class @NAME@ : public gr_sync_block
+{
+ friend @SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k);
+
+ std::vector<@I_TYPE@> d_k; // the constant
+ @NAME@ (const std::vector<@I_TYPE@> k);
+
+ public:
+ const std::vector<@I_TYPE@> k () const { return d_k; }
+ void set_k (const std::vector<@I_TYPE@> k) { d_k = k; }
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_add_const_vXX.i.t b/gnuradio-core/src/lib/general/gr_add_const_vXX.i.t
new file mode 100755
index 0000000000..38c399438a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_add_const_vXX.i.t
@@ -0,0 +1,37 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k);
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+ @NAME@ (const std::vector<@I_TYPE@> k);
+
+ public:
+ std::vector<@I_TYPE@> k () const { return d_k; }
+ void set_k (const std::vector<@I_TYPE@> k) { d_k = k; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_add_vXX.cc.t b/gnuradio-core/src/lib/general/gr_add_vXX.cc.t
new file mode 100755
index 0000000000..480b4a4582
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_add_vXX.cc.t
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (size_t nitems_per_block)
+{
+ return @SPTR_NAME@ (new @NAME@ (nitems_per_block));
+}
+
+@NAME@::@NAME@ (size_t nitems_per_block)
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (1, -1, sizeof (@I_TYPE@)*nitems_per_block),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@)*nitems_per_block))
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0];
+
+ int ninputs = input_items.size ();
+ int nitems_per_block = output_signature()->sizeof_stream_item(0)/sizeof(@I_TYPE@);
+
+ for (int i = 0; i < noutput_items; i++){
+ for (int j = 0; j < nitems_per_block; j++){
+ @I_TYPE@ acc = ((@I_TYPE@ *) input_items[0])[i*nitems_per_block+j];
+ for (int k = 1; k < ninputs; k++)
+ acc += ((@I_TYPE@ *) input_items[k])[i*nitems_per_block+j];
+
+ *optr++ = (@O_TYPE@) acc;
+ }
+ }
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_add_vXX.h.t b/gnuradio-core/src/lib/general/gr_add_vXX.h.t
new file mode 100755
index 0000000000..29a0b03b09
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_add_vXX.h.t
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (size_t nitems_per_block);
+
+/*!
+ * \brief output = sum (input_0, input_1, ...)
+ * \ingroup block
+ *
+ * Add across all input vectors.
+ */
+class @NAME@ : public gr_sync_block
+{
+ friend @SPTR_NAME@ gr_make_@BASE_NAME@ (size_t nitems_per_block);
+
+ @NAME@ (size_t nitems_per_block);
+
+ public:
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_add_vXX.i.t b/gnuradio-core/src/lib/general/gr_add_vXX.i.t
new file mode 100755
index 0000000000..0810961039
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_add_vXX.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (size_t nitems_per_block);
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+ @NAME@ (size_t nitems_per_block);
+};
diff --git a/gnuradio-core/src/lib/general/gr_agc_cc.cc b/gnuradio-core/src/lib/general/gr_agc_cc.cc
new file mode 100644
index 0000000000..7249ee1525
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_agc_cc.cc
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_agc_cc.h>
+#include <gr_io_signature.h>
+#include <gri_agc_cc.h>
+
+gr_agc_cc_sptr
+gr_make_agc_cc (float rate, float reference, float gain, float max_gain)
+{
+ return gr_agc_cc_sptr (new gr_agc_cc (rate, reference, gain, max_gain));
+}
+
+gr_agc_cc::gr_agc_cc (float rate, float reference, float gain, float max_gain)
+ : gr_sync_block ("gr_agc_cc",
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex)))
+ , gri_agc_cc (rate, reference, gain, max_gain)
+{
+}
+
+int
+gr_agc_cc::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *in = (const gr_complex *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+ scaleN (out, in, noutput_items);
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_agc_cc.h b/gnuradio-core/src/lib/general/gr_agc_cc.h
new file mode 100644
index 0000000000..c7676a516a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_agc_cc.h
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_AGC_CC_H
+#define INCLUDED_GR_AGC_CC_H
+
+#include <gr_sync_block.h>
+#include <gri_agc_cc.h>
+class gr_agc_cc;
+typedef boost::shared_ptr<gr_agc_cc> gr_agc_cc_sptr;
+
+gr_agc_cc_sptr
+gr_make_agc_cc (float rate = 1e-4, float reference = 1.0, float gain = 1.0, float max_gain = 0.0);
+/*!
+ * \brief high performance Automatic Gain Control class
+ *
+ * For Power the absolute value of the complex number is used.
+ */
+
+class gr_agc_cc : public gr_sync_block, public gri_agc_cc
+{
+ friend gr_agc_cc_sptr gr_make_agc_cc (float rate, float reference, float gain, float max_gain);
+ gr_agc_cc (float rate, float reference, float gain, float max_gain);
+
+ public:
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_AGC_CC_H */
diff --git a/gnuradio-core/src/lib/general/gr_agc_cc.i b/gnuradio-core/src/lib/general/gr_agc_cc.i
new file mode 100644
index 0000000000..79ebf19dda
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_agc_cc.i
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,agc_cc)
+
+%include <gri_agc_cc.i>
+
+gr_agc_cc_sptr
+gr_make_agc_cc (float rate = 1e-4, float reference = 1.0, float gain = 1.0, float max_gain = 0.0);
+
+class gr_agc_cc : public gr_sync_block , public gri_agc_cc
+{
+ gr_agc_cc (float rate, float reference, float gain, float max_gain);
+};
diff --git a/gnuradio-core/src/lib/general/gr_agc_ff.cc b/gnuradio-core/src/lib/general/gr_agc_ff.cc
new file mode 100644
index 0000000000..6b0d01e7b8
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_agc_ff.cc
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_agc_ff.h>
+#include <gr_io_signature.h>
+#include <gri_agc.h>
+
+gr_agc_ff_sptr
+gr_make_agc_ff (float rate, float reference, float gain, float max_gain)
+{
+ return gr_agc_ff_sptr (new gr_agc_ff (rate, reference, gain, max_gain));
+}
+
+gr_agc_ff::gr_agc_ff (float rate, float reference, float gain, float max_gain)
+ : gr_sync_block ("gr_agc_ff",
+ gr_make_io_signature (1, 1, sizeof (float)),
+ gr_make_io_signature (1, 1, sizeof (float)))
+ , gri_agc (rate, reference, gain, max_gain)
+{
+}
+
+int
+gr_agc_ff::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+ float *out = (float *) output_items[0];
+ scaleN (out, in, noutput_items);
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_agc_ff.h b/gnuradio-core/src/lib/general/gr_agc_ff.h
new file mode 100644
index 0000000000..da7edb7aa2
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_agc_ff.h
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_AGC_FF_H
+#define INCLUDED_GR_AGC_FF_H
+
+#include <gr_sync_block.h>
+#include <gri_agc.h>
+class gr_agc_ff;
+typedef boost::shared_ptr<gr_agc_ff> gr_agc_ff_sptr;
+
+gr_agc_ff_sptr
+gr_make_agc_ff (float rate = 1e-4, float reference = 1.0, float gain = 1.0, float max_gain = 0.0);
+/*!
+ * \brief high performance Automatic Gain Control class
+ *
+ * Power is approximated by absolute value
+ */
+
+class gr_agc_ff : public gr_sync_block, public gri_agc
+{
+ friend gr_agc_ff_sptr gr_make_agc_ff (float rate, float reference, float gain, float max_gain);
+ gr_agc_ff (float rate, float reference, float gain, float max_gain);
+
+ public:
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_FLOAT_AGC_FF_H */
diff --git a/gnuradio-core/src/lib/general/gr_agc_ff.i b/gnuradio-core/src/lib/general/gr_agc_ff.i
new file mode 100644
index 0000000000..9b6312714d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_agc_ff.i
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,agc_ff)
+
+%include <gri_agc.i>
+
+gr_agc_ff_sptr
+gr_make_agc_ff (float rate = 1e-4, float reference = 1.0, float gain = 1.0, float max_gain = 0.0);
+
+class gr_agc_ff : public gr_sync_block , public gri_agc
+{
+ gr_agc_ff (float rate, float reference, float gain, float max_gain);
+};
diff --git a/gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.cc b/gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.cc
new file mode 100644
index 0000000000..005b575b43
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.cc
@@ -0,0 +1,461 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_align_on_samplenumbers_ss.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <stdexcept>
+
+//define ALIGN_ADVANCED_IMPLEMENTATION to have an alternative implementation of the align algoritm which exactly follows the align_interval spec.
+//It is more resource intensive, less tested and probably not needed
+//define ALIGN_ADVANCED_IMPLEMENTATION
+
+//define DEBUG_TOCONSUME to see debug messages about the synchronisation part of this block
+//define DEBUG_TOCONSUME
+#ifdef DEBUG_TOCONSUME
+#define tcPrintf if(dprint) printf
+#else
+#define tcPrintf //printf
+#endif
+
+#define ePrintf printf
+
+gr_align_on_samplenumbers_ss_sptr
+gr_make_align_on_samplenumbers_ss (int nchan, int align_interval)
+{
+ return gr_align_on_samplenumbers_ss_sptr (new gr_align_on_samplenumbers_ss (nchan,align_interval));
+}
+
+gr_align_on_samplenumbers_ss::gr_align_on_samplenumbers_ss (int nchan,int align_interval)
+ : gr_block ("align_on_samplenumbers_ss",
+ gr_make_io_signature (2, -1, sizeof (short)), //2, -1
+ gr_make_io_signature (2, -1, sizeof (short))), //2,-1
+ d_align_interval (align_interval),
+ d_nchan(nchan),
+ d_ninputs(0)
+{
+ if (d_align_interval<0)
+ set_output_multiple (d_nchan*2);
+ else
+ {
+ set_output_multiple (d_align_interval*d_nchan*2);
+ }
+
+}
+
+gr_align_on_samplenumbers_ss::~gr_align_on_samplenumbers_ss()
+{
+
+}
+void
+gr_align_on_samplenumbers_ss::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+ //assert (0 == noutput_items % d_align_interval);
+ unsigned ninputs = ninput_items_required.size();
+ for (unsigned int i = 0; i < ninputs; i++)
+ ninput_items_required[i] = std::max(noutput_items*d_nchan*2+ history() - 1,1024*d_nchan*2+ history() - 1);//TODO include the diffs found in determine input_items_required
+}
+
+bool
+gr_align_on_samplenumbers_ss::check_topology (int ninputs, int noutputs)
+{
+ bool result=true;
+ if(noutputs!=ninputs)
+ {
+ result=false;
+ ePrintf("gr_align_on_samplenumbers_ss: ERROR noutputs %i != ninputs %i\n",noutputs,ninputs);
+ }
+ if(d_nchan<2)
+ {
+ result=false;
+ ePrintf("gr_align_on_samplenumbers_ss: ERROR nchan %i<2 \n",d_nchan);
+ }
+ if((int)d_ninputs!=ninputs)
+ {
+ //Only resize and reset the status if there really changed something
+ //Don't reset the status if the user just called stop() and start(), although maybe we should.
+ d_state.resize(ninputs);
+ d_ninputs=ninputs;
+ for(unsigned int i=0;i<d_ninputs;i++)
+ {
+ d_state[i].sync_found=false;
+ d_state[i].sync_end_found=false;
+ }
+ d_in_presync=false;
+ }
+ return result;
+}
+
+#ifdef ALIGN_ADVANCED_IMPLEMENTATION
+int
+gr_align_on_samplenumbers_ss::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+#ifdef DEBUG_TOCONSUME
+ static int dcount=0;
+ bool dprint=false;
+ dcount++;
+ if(dcount>200)
+ {
+ dcount=0;
+ dprint=true;
+ }
+#endif
+ const size_t item_size = output_signature()->sizeof_stream_item (0);
+ const unsigned ninputs = input_items.size();
+ const unsigned noutputs = output_items.size();
+
+ int align_interval=d_align_interval*2*d_nchan;
+ if(d_align_interval<0)
+ {
+ //align once per noutput_items
+ align_interval=noutput_items;
+ align_interval=align_interval/(2*d_nchan);
+ align_interval=align_interval*(2*d_nchan);
+ }
+
+ int min_ninput_items=noutput_items;//numeric_limits<int>::max();
+ int noutput_items_produced=0;
+ for(unsigned int i=0;i<ninputs;i++)
+ {
+ d_state[i].ninput_items=ninput_items[i];
+ d_state[i].ninput_items_used=0;
+ min_ninput_items=std::min(ninput_items[i],min_ninput_items);
+ }
+ for(int j=0;j<noutput_items-align_interval+1;j+=align_interval)
+ {
+ int common_end;
+ if(min_ninput_items>=align_interval)
+ common_end=align_interval;
+ else
+ {
+ common_end=min_ninput_items/(d_nchan*2);
+ common_end=common_end*(d_nchan*2);
+ }
+ if (common_end<=0) break;
+
+ bool all_diffs_zero=true;
+ //bool sync_found=false;
+ int diff_comp_end_max=0;
+ for(unsigned int i=0;i<ninputs;i++)
+ {
+ unsigned short * uin=&(((unsigned short*)input_items[i])[d_state[i].ninput_items_used]);
+ unsigned int x_high16bits = uin[0];
+ unsigned int x_low16bits = uin[1];
+ d_state[i].ucounter_begin = x_high16bits<<16 | x_low16bits;
+ d_state[i].diff=d_state[0].ucounter_begin-d_state[i].ucounter_begin;//Result is a signed value,Will wrap around on 32 bit boundary
+ int common_last=std::max(common_end-d_nchan*2,0);
+ x_high16bits = uin[d_nchan*2];
+ x_low16bits = uin[d_nchan*2+1];
+ unsigned int ucounter_begin2 = x_high16bits<<16 | x_low16bits;
+#ifdef DEBUG_TOCONSUME
+ if((d_state[i].ucounter_begin+1)!=(ucounter_begin2))
+ if(ucounter_begin2==0)
+ ePrintf("SYNC counters are 0\n");
+ else
+ ePrintf("Error: counter not continuous.\n ucounter_begin[%i]=%i +1 != ucounter_begin2=%i\n",i,d_state[i].ucounter_begin,ucounter_begin2);
+#endif
+ x_high16bits = uin[common_last];
+ x_low16bits = uin[common_last+1];
+ d_state[i].ucounter_end = x_high16bits<<16 | x_low16bits;
+ d_state[i].diff_end=d_state[0].ucounter_end-d_state[i].ucounter_end;//Result is a signed value,Will wrap around on 32 bit boundary
+ d_state[i].diff_comp_end=d_state[i].ucounter_end-d_state[0].ucounter_end;
+ diff_comp_end_max=std::max(d_state[i].diff_comp_end,diff_comp_end_max);
+#ifdef DEBUG_TOCONSUME
+ if(d_state[i].diff>256000000 || d_state[i].diff_end>256000000 || d_state[i].diff_comp_end>256000000)
+ {
+ tcPrintf("diff[%i]=%i diff_end=%i diff_comp_end=%i\n",i,d_state[i].diff,d_state[i].diff_end,d_state[i].diff_comp_end);
+ }
+#endif
+ all_diffs_zero=all_diffs_zero && (0==d_state[i].diff_end);
+ if(d_state[i].ucounter_end<d_state[i].ucounter_begin+(unsigned)(common_last/(d_nchan*2))) //(unsigned)(common_last/(d_nchan*2)))
+ {
+ //printf("sync 1 ");// found ucounter_end[%i]=%i ucounter_begin[%i]=%i \n",i,d_state[i].ucounter_end,i,d_state[i].ucounter_begin);
+ //sync_found=true;//sync_found or 32 bit counter wraparound (0xffffffff -> 0x00000000)
+ if(!d_in_presync)
+ {
+#ifdef DEBUG_TOCONSUME
+ printf("presync START with %i\n",i);
+#endif
+ for(unsigned int k=0;k<ninputs;k++)
+ {
+ d_state[k].sync_found=false;
+ d_state[i].sync_end_found=false;
+ }
+ d_in_presync=true;
+ d_state[i].sync_found=true;
+ } else
+ {
+ //d_in_presync=true;
+#ifdef DEBUG_TOCONSUME
+ if(d_state[i].sync_found)
+ printf("presync CONTINUE with %i\n",i);
+ else
+ printf("presync NEXT with %i\n",i);
+#endif
+ d_state[i].sync_found=true;
+ d_state[i].sync_end_found=false;
+ }
+ } else
+ {
+ if(d_in_presync && d_state[i].sync_found)
+ {
+ d_state[i].sync_end_found=true;
+ bool all_syncs_found=true;
+ for(unsigned int k=0;k<ninputs;k++)
+ all_syncs_found=all_syncs_found && d_state[k].sync_end_found;
+ d_in_presync=!all_syncs_found;
+ if(!d_in_presync)
+ {
+ for(unsigned int k=0;k<ninputs;k++)
+ {
+ d_state[k].sync_found=false;
+ d_state[i].sync_end_found=false;
+ }
+#ifdef DEBUG_TOCONSUME
+ printf("presync END\n");
+#endif
+ }
+ }
+ }
+ }
+ if(d_in_presync || all_diffs_zero)
+ {
+ for(unsigned int i=0;i<ninputs;i++)
+ {
+ memcpy(&(((unsigned short*)output_items[i])[j]),&(((const unsigned short*)input_items[i])[d_state[i].ninput_items_used]),common_end*item_size);
+ //consume(i,common_end);
+ d_state[i].ninput_items-=common_end;
+ d_state[i].ninput_items_used+=common_end;
+ min_ninput_items=std::min(d_state[i].ninput_items,min_ninput_items);
+#ifdef DEBUG_TOCONSUME
+ if(common_end<256)
+ tcPrintf("common_end %i\n",common_end);
+#endif
+ }
+ //min_ninput_items-=common_end;
+ noutput_items_produced+=common_end;
+ //return common_end;
+ } else
+ {
+ //printf("sync 2");
+ for(unsigned int i=0;i<ninputs;i++)
+ {
+ int toconsume=std::min((d_state[i].diff_end+diff_comp_end_max)*d_nchan*2,d_state[i].ninput_items);
+ toconsume=toconsume/(d_nchan*2);
+ toconsume=toconsume*(d_nchan*2);
+ d_state[i].ninput_items-=toconsume;
+ d_state[i].ninput_items_used+=toconsume;
+ min_ninput_items=std::min(d_state[i].ninput_items,min_ninput_items);
+#ifdef DEBUG_TOCONSUME
+ static int toconsume_counter=0;
+ toconsume_counter++;
+ //if(toconsume_counter>10)
+ {
+ tcPrintf("toconsume=%i diff_end[%i]*d_nchan*2=%i diff_comp_end_max*d_nchan*2=%i ninput_items[%i]=%i\n",toconsume,i,d_state[i].diff_end*d_nchan*2,diff_comp_end_max*d_nchan*2,i,ninput_items[i]);
+ toconsume_counter=0;
+ }
+#endif
+ //printf("toconsume[%i]=%i\n",i,toconsume);
+ //consume(i,toconsume);//skip the difference in samplenumber items
+ }
+ //return 0;
+ }
+ }
+ for(unsigned int i=0;i<ninputs;i++)
+ consume(i,d_state[i].ninput_items_used);
+#ifdef DEBUG_TOCONSUME
+ if(noutput_items_produced<256)
+ tcPrintf("noutput_items_produced %i\n",noutput_items_produced);
+#endif
+ return noutput_items_produced;
+}
+
+
+#else /*ALIGN_ADVANCED_IMPLEMENTATION*/
+int
+gr_align_on_samplenumbers_ss::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+#ifdef DEBUG_TOCONSUME
+ static int dcount=0;
+ bool dprint=false;
+ dcount++;
+ if(dcount>2000)
+ {
+ dcount=0;
+ dprint=true;
+ }
+#endif
+ const size_t item_size = output_signature()->sizeof_stream_item (0);
+ const unsigned ninputs = input_items.size();
+
+ int common_end=noutput_items;
+ //int diff_min=INT_MAX;
+ //int diff_max=INT_MIN;
+ for(unsigned int i=0;i<ninputs;i++)
+ {
+ unsigned short * uin=(unsigned short*)input_items[i];
+ unsigned int x_high16bits = uin[0];
+ unsigned int x_low16bits = uin[1];
+ d_state[i].ucounter_begin = x_high16bits<<16 | x_low16bits;
+ d_state[i].diff=d_state[0].ucounter_end-d_state[i].ucounter_end;//Result is a signed value,Will wrap around on 32 bit boundary
+ x_high16bits = uin[d_nchan*2];
+ x_low16bits = uin[d_nchan*2+1];
+ unsigned int ucounter_begin2 = x_high16bits<<16 | x_low16bits;
+ if((d_state[i].ucounter_begin+1)!=(ucounter_begin2))
+ if(ucounter_begin2==0)
+ {
+#ifdef DEBUG_TOCONSUME
+ ePrintf("SYNC counters are 0\n");
+#endif
+ }
+ else
+ {
+ ePrintf("Error: counter not continuous.\n ucounter_begin[%i]=%i +1 != ucounter_begin2=%i\n",i,d_state[i].ucounter_begin,ucounter_begin2);
+ }
+
+ //diff_comp[i]=ucounter[i]-ucounter[0];
+ //diff_min=std::min(diff[i],diff_min);
+ //diff_max=std::max(diff[i],diff_max);
+ common_end=std::max(std::min(ninput_items[i],common_end),0);
+ }
+ common_end=common_end/(d_nchan*2);
+ common_end=common_end*(d_nchan*2);
+#ifdef DEBUG_TOCONSUME
+ if(common_end<d_nchan*2)
+ {
+ printf(" common_end %i\n",common_end);
+ for(int j=0;j<ninputs;j++)
+ printf("ninput_items[%i]=%i\n",j,ninput_items[j]);
+ }
+#endif
+ bool all_diffs_zero=true;
+ bool sync_found=false;
+ int diff_comp_end_max=0;
+ for(unsigned int i=0;i<ninputs;i++)
+ {
+ unsigned short * uin=(unsigned short*)input_items[i];
+ int common_last=common_end-(d_nchan*2);
+ unsigned int x_high16bits = uin[common_last];
+ unsigned int x_low16bits = uin[common_last+1];
+ d_state[i].ucounter_end = x_high16bits<<16 | x_low16bits;
+ d_state[i].diff_end=d_state[0].ucounter_end-d_state[i].ucounter_end;//Result is a signed value,Will wrap around on 32 bit boundary
+ d_state[i].diff_comp_end=d_state[i].ucounter_end-d_state[0].ucounter_end;
+ //diff_end_min=std::min(diff_end[i],diff_end_min);
+ //diff_end_max=std::max(diff_end[i],diff_end_max);
+ diff_comp_end_max=std::max(d_state[i].diff_comp_end,diff_comp_end_max);
+#ifdef DEBUG_TOCONSUME
+ if(d_state[i].diff_end!=d_state[i].diff)
+ {
+ //samples_lost_or_syncstart=true;
+ printf("Us%i %i %i ",i,d_state[i].diff_end,d_state[i].diff);
+ }
+#endif
+ all_diffs_zero=all_diffs_zero && (0==d_state[i].diff_end);
+ if((d_state[i].ucounter_end<d_state[i].ucounter_begin+(unsigned)(common_last/(d_nchan*2))) || (0==d_state[i].ucounter_end) || (0==d_state[i].ucounter_begin)) //(unsigned)(common_last/(d_nchan*2)))
+ {
+ sync_found=true;//sync_found or 32 bit counter wraparound (0xffffffff -> 0x00000000)
+#ifdef DEBUG_TOCONSUME
+ tcPrintf("SYNC diff_end[%i]=%i ucounter_end[%i]=%i ucounter_begin[%i]=%i \n",i,d_state[i].diff_end,i,d_state[i].ucounter_end,i,d_state[i].ucounter_begin);
+ tcPrintf("ucounter_end=%i < %i = ucounter_begin+(unsigned)(common_last/(d_nchan*2) \n",d_state[i].ucounter_end,d_state[i].ucounter_begin+(unsigned)(common_last/(d_nchan*2)));
+
+ printf("ucounter_end[%i]=%i ucounter_begin[%i]=%i\n",i,d_state[i].ucounter_end,i,d_state[i].ucounter_begin);
+ int expected_sync_position=common_last - d_state[i].ucounter_end*(d_nchan*2);
+ if(0==uin[expected_sync_position] && 0==uin[expected_sync_position+1])
+ {
+ printf("sync found on input %i at position %i \n",i,expected_sync_position);
+ //sync_start[i]=expected_sync_position;
+ } else
+ {
+ printf("sync found on input %i position unclear, expected at %i value there %i\n",i,expected_sync_position,uin[expected_sync_position]<<16 | uin[expected_sync_position+1]);
+ //sync_start[i]=-1;
+ }
+ } else
+ {
+ tcPrintf("NOsync diff_end[%i]=%i ucounter_end[%i]=%i ucounter_begin[%i]=%i \n",i,d_state[i].diff_end,i,d_state[i].ucounter_end,i,d_state[i].ucounter_begin);
+#endif
+ }
+ }
+ bool problem=false;
+ for(unsigned int i=0;i<ninputs;i++)
+ if((d_state[i].diff_end+diff_comp_end_max) >0x4000000)
+ {
+ problem=true;
+ ePrintf("Warning: counter diff greater as 64 Million\n");
+ ePrintf(" You might want to swap master and slave.\n");
+ ePrintf(" i=%i,d_state[i].diff_end+diff_comp_end_max=%i,d_state[i].diff_end=%i,diff_comp_end_max=%i,ucounter[i]=%i,ucounter[0]=%i\n",
+ i,d_state[i].diff_end+diff_comp_end_max,d_state[i].diff_end,diff_comp_end_max,d_state[i].ucounter_end,d_state[0].ucounter_end);
+ //ePrintf(" toconsume=%i\n",toconsume);
+ }
+ if(sync_found || all_diffs_zero || problem)
+ {
+#ifdef DEBUG_TOCONSUME
+ if(all_diffs_zero) tcPrintf("ZERO\n");
+ if(sync_found) tcPrintf("SYNC\n");
+#endif
+ for(unsigned int i=0;i<ninputs;i++)
+ {
+ memcpy(output_items[i],input_items[i],common_end*item_size);
+ consume(i,common_end);
+#ifdef DEBUG_TOCONSUME
+ if(common_end<256)
+ tcPrintf("common_end %i\n",common_end);
+#endif
+ }
+ return common_end;
+ } else
+ {
+ //int minconsume=0;//common_end/(2*d_nchan*2);
+ //min_consume=min_consume*d_nchan*2;
+ for(unsigned int i=0;i<ninputs;i++)
+ {
+ int toconsume=std::min((d_state[i].diff_end+diff_comp_end_max)*d_nchan*2,ninput_items[i]);
+ toconsume=toconsume/(d_nchan*2);
+ toconsume=toconsume*(d_nchan*2);
+#ifdef DEBUG_TOCONSUME
+ //printf("dcount %i\n",dcount);
+ static int toconsume_counter=0;
+ toconsume_counter++;
+ //if(toconsume_counter>10)
+ {
+ tcPrintf("toconsume=%i diff_end[[%i]*d_nchan*2=%i diff_comp_end_max)*d_nchan*2=%i ninput_items[%i]=%i\n",
+ toconsume,i,d_state[i].diff_end*d_nchan*2,diff_comp_end_max*d_nchan*2,i,ninput_items[i]);
+ toconsume_counter=0;
+ }
+#endif
+ consume(i,toconsume);//skip the difference in samplenumber items
+ //printf("toconsume%i %i diff_comp_end_max %i diff_end[[%i] %i\n",i,toconsume,diff_comp_end_max,i,d_state[i].diff_end);
+ }
+ return 0;
+ }
+ return -1;//Should never come here
+}
+#endif /*ALIGN_ADVANCED_IMPLEMENTATION*/
diff --git a/gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.h b/gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.h
new file mode 100644
index 0000000000..69d68b2aac
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.h
@@ -0,0 +1,89 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_ALIGN_ON_SAMPLE_NUMBERS_SS_H
+#define INCLUDED_GR_ALIGN_ON_SAMPLE_NUMBERS_SS_H
+
+#include <gr_block.h>
+
+class gr_align_on_samplenumbers_ss;
+typedef boost::shared_ptr<gr_align_on_samplenumbers_ss> gr_align_on_samplenumbers_ss_sptr;
+
+gr_align_on_samplenumbers_ss_sptr gr_make_align_on_samplenumbers_ss (int nchan=2, int align_interval=128);
+
+/*!
+ * \brief align several complex short (interleaved short) input channels with corresponding unsigned 32 bit sample_counters (provided as interleaved 16 bit values)
+ * \param number of complex_short input channels (including the 32 bit counting channel)
+ * \param align_interval is after how much samples (minimally) the sample-alignement is refreshed. Default is 128.
+ * A bigger value means less processing power but also requests more buffer space, which has a maximum.
+ * Decrease the align_interval if you get an error like:
+ * "sched: <gr_block align_on_samplenumbers_ss (0)> is requesting more input data than we can provide.
+ * ninput_items_required = 32768
+ * max_possible_items_available = 16383
+ * If this is a filter, consider reducing the number of taps."
+ * \ingroup block
+ * Pay attention on how you connect this block.
+ * It expects a minimum of 2 usrp_source_s with nchan number of channels and FPGA_MODE_COUNTING_32BIT enabled.
+ * This means that the first complex_short channel on every input is an interleaved 32 bit counter.
+ * The samples are aligned by dropping samples untill the samplenumbers match.
+ */
+
+
+class gr_align_on_samplenumbers_ss : public gr_block
+{
+ int d_align_interval;
+ int d_sample_counter;
+ int d_nchan;
+ bool d_in_presync;
+ unsigned int d_ninputs;
+ class align_state {
+ public:
+ unsigned int ucounter_end;
+ unsigned int ucounter_begin;
+ int diff;
+ int diff_comp;
+ int diff_end;
+ int diff_comp_end;
+ bool sync_found;
+ bool sync_end_found;
+ int ninput_items;
+ int ninput_items_used;
+ };
+ std::vector<align_state> d_state;
+
+ friend gr_align_on_samplenumbers_ss_sptr gr_make_align_on_samplenumbers_ss (int nchan,int align_interval);
+ gr_align_on_samplenumbers_ss (int nchan,int align_interval);
+
+ public:
+ ~gr_align_on_samplenumbers_ss();
+ bool check_topology (int ninputs, int noutputs);
+ void forecast (int noutput_items,
+ gr_vector_int &ninput_items_required);
+
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_ALIGN_ON_SAMPLE_NUMBERS_SS_H */
diff --git a/gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.i b/gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.i
new file mode 100644
index 0000000000..00d3174973
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,align_on_samplenumbers_ss);
+
+gr_align_on_samplenumbers_ss_sptr gr_make_align_on_samplenumbers_ss(int nchan=2, int align_interval=128);
+
+class gr_align_on_samplenumbers_ss : public gr_block
+{
+ public:
+ ~gr_align_on_samplenumbers_ss ();
+ private:
+ gr_align_on_samplenumbers_ss (int nchan,int align_interval);
+};
diff --git a/gnuradio-core/src/lib/general/gr_binary_slicer_fb.cc b/gnuradio-core/src/lib/general/gr_binary_slicer_fb.cc
new file mode 100644
index 0000000000..a74746d32f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_binary_slicer_fb.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_binary_slicer_fb.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+gr_binary_slicer_fb_sptr
+gr_make_binary_slicer_fb ()
+{
+ return gr_binary_slicer_fb_sptr (new gr_binary_slicer_fb ());
+}
+
+gr_binary_slicer_fb::gr_binary_slicer_fb ()
+ : gr_sync_block ("binary_slicer_fb",
+ gr_make_io_signature (1, 1, sizeof (float)),
+ gr_make_io_signature (1, 1, sizeof (unsigned char)))
+{
+}
+
+static inline int
+slice(float x)
+{
+ return x < 0 ? 0 : 1;
+}
+
+int
+gr_binary_slicer_fb::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+
+
+ for (int i = 0; i < noutput_items; i++){
+ out[i] = slice(in[i]);
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_binary_slicer_fb.h b/gnuradio-core/src/lib/general/gr_binary_slicer_fb.h
new file mode 100644
index 0000000000..ce755718f7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_binary_slicer_fb.h
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_BINARY_SLICER_FB_H
+#define INCLUDED_GR_BINARY_SLICER_FB_H
+
+#include <gr_sync_block.h>
+
+class gr_binary_slicer_fb;
+typedef boost::shared_ptr<gr_binary_slicer_fb> gr_binary_slicer_fb_sptr;
+
+gr_binary_slicer_fb_sptr gr_make_binary_slicer_fb ();
+
+/*!
+ * \brief slice float binary symbol outputting 1 bit output
+ * \ingroup block
+ *
+ * x < 0 --> 0
+ * x >= 0 --> 1
+ */
+class gr_binary_slicer_fb : public gr_sync_block
+{
+ friend gr_binary_slicer_fb_sptr gr_make_binary_slicer_fb ();
+ gr_binary_slicer_fb ();
+
+ public:
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_binary_slicer_fb.i b/gnuradio-core/src/lib/general/gr_binary_slicer_fb.i
new file mode 100644
index 0000000000..0d66429bf5
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_binary_slicer_fb.i
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,binary_slicer_fb);
+
+gr_binary_slicer_fb_sptr gr_make_binary_slicer_fb ();
+
+class gr_binary_slicer_fb : public gr_sync_block
+{
+ private:
+ gr_binary_slicer_fb ();
+
+ public:
+};
diff --git a/gnuradio-core/src/lib/general/gr_bytes_to_syms.cc b/gnuradio-core/src/lib/general/gr_bytes_to_syms.cc
new file mode 100644
index 0000000000..3b492cdb94
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_bytes_to_syms.cc
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_bytes_to_syms.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+
+static const int BITS_PER_BYTE = 8;
+
+gr_bytes_to_syms_sptr
+gr_make_bytes_to_syms ()
+{
+ return gr_bytes_to_syms_sptr (new gr_bytes_to_syms ());
+}
+
+gr_bytes_to_syms::gr_bytes_to_syms ()
+ : gr_sync_interpolator ("bytes_to_syms",
+ gr_make_io_signature (1, 1, sizeof (unsigned char)),
+ gr_make_io_signature (1, 1, sizeof (float)),
+ BITS_PER_BYTE)
+{
+}
+
+int
+gr_bytes_to_syms::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (unsigned char *) input_items[0];
+ float *out = (float *) output_items[0];
+
+ assert (noutput_items % BITS_PER_BYTE == 0);
+
+ for (int i = 0; i < noutput_items / BITS_PER_BYTE; i++){
+ int x = in[i];
+
+ *out++ = (((x >> 7) & 0x1) << 1) - 1;
+ *out++ = (((x >> 6) & 0x1) << 1) - 1;
+ *out++ = (((x >> 5) & 0x1) << 1) - 1;
+ *out++ = (((x >> 4) & 0x1) << 1) - 1;
+ *out++ = (((x >> 3) & 0x1) << 1) - 1;
+ *out++ = (((x >> 2) & 0x1) << 1) - 1;
+ *out++ = (((x >> 1) & 0x1) << 1) - 1;
+ *out++ = (((x >> 0) & 0x1) << 1) - 1;
+ }
+
+ return noutput_items;
+}
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_bytes_to_syms.h b/gnuradio-core/src/lib/general/gr_bytes_to_syms.h
new file mode 100644
index 0000000000..72f844d4f9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_bytes_to_syms.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_BYTES_TO_SYMS_H
+#define INCLUDED_GR_BYTES_TO_SYMS_H
+
+#include <gr_sync_interpolator.h>
+
+class gr_bytes_to_syms;
+typedef boost::shared_ptr<gr_bytes_to_syms> gr_bytes_to_syms_sptr;
+
+gr_bytes_to_syms_sptr gr_make_bytes_to_syms ();
+
+/*!
+ * \brief Convert stream of bytes to stream of +/- 1 symbols
+ * \ingroup block
+ *
+ * input: stream of bytes; output: stream of float
+ *
+ * This block is deprecated.
+ *
+ * The combination of gr_packed_to_unpacked_bb followed by
+ * gr_chunks_to_symbols_bf or gr_chunks_to_symbols_bc handles the
+ * general case of mapping from a stream of bytes into arbitrary float
+ * or complex symbols.
+ *
+ * \sa gr_packed_to_unpacked_bb, gr_unpacked_to_packed_bb,
+ * \sa gr_chunks_to_symbols_bf, gr_chunks_to_symbols_bc.
+ */
+class gr_bytes_to_syms : public gr_sync_interpolator
+{
+ friend gr_bytes_to_syms_sptr gr_make_bytes_to_syms ();
+
+ gr_bytes_to_syms ();
+
+ public:
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_BYTES_TO_SYMS_H */
diff --git a/gnuradio-core/src/lib/general/gr_bytes_to_syms.i b/gnuradio-core/src/lib/general/gr_bytes_to_syms.i
new file mode 100644
index 0000000000..33ef089d0b
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,bytes_to_syms);
+
+gr_bytes_to_syms_sptr gr_make_bytes_to_syms ();
+
+class gr_bytes_to_syms : public gr_sync_interpolator
+{
+ gr_bytes_to_syms ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_char_to_float.cc b/gnuradio-core/src/lib/general/gr_char_to_float.cc
new file mode 100644
index 0000000000..c4151eeeec
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_char_to_float.cc
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_char_to_float.h>
+#include <gr_io_signature.h>
+#include <gri_char_to_float.h>
+
+gr_char_to_float_sptr
+gr_make_char_to_float ()
+{
+ return gr_char_to_float_sptr (new gr_char_to_float ());
+}
+
+gr_char_to_float::gr_char_to_float ()
+ : gr_sync_block ("gr_char_to_float",
+ gr_make_io_signature (1, 1, sizeof (char)),
+ gr_make_io_signature (1, 1, sizeof (float)))
+{
+}
+
+int
+gr_char_to_float::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const char *in = (const char *) input_items[0];
+ float *out = (float *) output_items[0];
+
+ gri_char_to_float (in, out, noutput_items);
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_char_to_float.h b/gnuradio-core/src/lib/general/gr_char_to_float.h
new file mode 100644
index 0000000000..d2b287ff3b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_char_to_float.h
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_CHAR_TO_FLOAT_H
+#define INCLUDED_GR_CHAR_TO_FLOAT_H
+
+#include <gr_sync_block.h>
+
+class gr_char_to_float;
+typedef boost::shared_ptr<gr_char_to_float> gr_char_to_float_sptr;
+
+gr_char_to_float_sptr
+gr_make_char_to_float ();
+
+/*!
+ * \brief Convert stream of chars to a stream of float
+ * \ingroup converter
+ */
+
+class gr_char_to_float : public gr_sync_block
+{
+ friend gr_char_to_float_sptr gr_make_char_to_float ();
+ gr_char_to_float ();
+
+ public:
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_CHAR_TO_FLOAT_H */
diff --git a/gnuradio-core/src/lib/general/gr_char_to_float.i b/gnuradio-core/src/lib/general/gr_char_to_float.i
new file mode 100644
index 0000000000..3f1c7e19f4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_char_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,char_to_float)
+
+gr_char_to_float_sptr gr_make_char_to_float ();
+
+class gr_char_to_float : public gr_sync_block
+{
+ gr_char_to_float ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_check_counting_s.cc b/gnuradio-core/src/lib/general/gr_check_counting_s.cc
new file mode 100644
index 0000000000..59e740c10d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_check_counting_s.cc
@@ -0,0 +1,190 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_check_counting_s.h>
+#include <gr_io_signature.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+gr_check_counting_s_sptr
+gr_make_check_counting_s (bool do_32bit)
+{
+ return gr_check_counting_s_sptr (new gr_check_counting_s (do_32bit));
+}
+
+gr_check_counting_s::gr_check_counting_s (bool do_32bit)
+ : gr_sync_block ("gr_check_counting",
+ gr_make_io_signature (1, 1, sizeof (short)),
+ gr_make_io_signature (0, 0, 0)),
+ d_state(SEARCHING), d_history (0), d_current_count (0), d_current_count_32bit(0),
+ d_total_errors (0), d_total_shorts (0),
+ d_do_32bit(do_32bit)
+{
+ enter_SEARCHING ();
+}
+
+int
+gr_check_counting_s::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ unsigned short *in = (unsigned short *) input_items[0];
+ if(d_do_32bit)
+ return check_32bit(noutput_items,in);
+ else
+ return check_16bit(noutput_items,in);
+}
+
+int
+gr_check_counting_s::check_16bit (int noutput_items,
+ unsigned short * in)
+{
+ for (int i = 0; i < noutput_items; i++){
+ unsigned short x = in[i];
+
+ switch (d_state){
+
+ case SEARCHING:
+ if (x == d_current_count){
+ right ();
+ log_error (d_current_count, x);
+ d_current_count = d_current_count + 1;
+ if (right_three_times ())
+ enter_LOCKED ();
+ }
+ else {
+ wrong ();
+ log_error (d_current_count, x);
+ d_current_count = x + 1;
+ }
+ break;
+
+ case LOCKED:
+ if (x == d_current_count){
+ right ();
+ d_current_count = d_current_count + 1;
+ }
+ else {
+ wrong ();
+ log_error (d_current_count, x);
+ d_current_count = d_current_count + 1;
+ if (wrong_three_times ())
+ enter_SEARCHING ();
+ }
+ break;
+
+ default:
+ abort ();
+ }
+
+ d_total_shorts++;
+ }
+
+ return noutput_items;
+}
+
+int
+gr_check_counting_s::check_32bit (int noutput_items,
+ unsigned short * in)
+{
+
+ for (int i = 0; i < noutput_items-1; i+=2){
+ unsigned int x_high16bits = in[i];
+ unsigned int x_low16bits = in[i+1];
+ unsigned int x = x_high16bits<<16 | x_low16bits;
+
+ switch (d_state){
+
+ case SEARCHING:
+ if (x == d_current_count_32bit){
+ right ();
+ log_error_32bit (d_current_count_32bit, x);
+ d_current_count_32bit = d_current_count_32bit + 1;
+ if (right_three_times ())
+ enter_LOCKED ();
+ }
+ else {
+ wrong ();
+ log_error_32bit (d_current_count_32bit, x);
+ d_current_count_32bit = x + 1;
+ }
+ break;
+
+ case LOCKED:
+ if (x == d_current_count_32bit){
+ right ();
+ d_current_count_32bit = d_current_count_32bit + 1;
+ }
+ else {
+ wrong ();
+ log_error_32bit (d_current_count_32bit, x);
+ d_current_count_32bit = d_current_count_32bit + 1;
+ if (wrong_three_times ())
+ enter_SEARCHING ();
+ }
+ break;
+
+ default:
+ abort ();
+ }
+
+ d_total_shorts++;
+ }
+
+ return noutput_items;
+}
+
+void
+gr_check_counting_s::enter_SEARCHING ()
+{
+ d_state = SEARCHING;
+ fprintf (stdout, "gr_check_counting: enter_SEARCHING at offset %8ld (0x%08lx)\n",
+ d_total_shorts, d_total_shorts);
+}
+
+void
+gr_check_counting_s::enter_LOCKED ()
+{
+ d_state = LOCKED;
+ fprintf (stdout, "gr_check_counting: enter_LOCKED at offset %8ld (0x%08lx)\n",
+ d_total_shorts, d_total_shorts);
+}
+
+void
+gr_check_counting_s::log_error (unsigned short expected, unsigned short actual)
+{
+ fprintf (stdout,
+"gr_check_counting: expected %5d (0x%04x) got %5d (0x%04x) offset %8ld (0x%08lx)\n",
+ expected, expected, actual, actual, d_total_shorts, d_total_shorts);
+}
+
+void
+gr_check_counting_s::log_error_32bit (unsigned int expected, unsigned int actual)
+{
+ fprintf (stdout,
+"gr_check_counting: expected %10d (0x%08x) got %10d (0x%08x) offset %8ld (0x%08lx)\n",
+ expected, expected, actual, actual, d_total_shorts, d_total_shorts);
+}
diff --git a/gnuradio-core/src/lib/general/gr_check_counting_s.h b/gnuradio-core/src/lib/general/gr_check_counting_s.h
new file mode 100644
index 0000000000..3037e9f0d0
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_check_counting_s.h
@@ -0,0 +1,88 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_CHECK_COUNTING_S_H
+#define INCLUDED_GR_CHECK_COUNTING_S_H
+
+#include <gr_sync_block.h>
+
+class gr_check_counting_s;
+typedef boost::shared_ptr<gr_check_counting_s> gr_check_counting_s_sptr;
+
+gr_check_counting_s_sptr gr_make_check_counting_s (bool do_32bit=false);
+
+/*!
+ * \brief sink that checks if its input stream consists of a counting sequence.
+ * \param do_32bit expect an interleaved 32 bit counter in stead of 16 bit counter (default false)
+ * \ingroup sink
+ *
+ * This sink is typically used to test the USRP "Counting Mode" or "Counting mode 32 bit".
+ */
+class gr_check_counting_s : public gr_sync_block
+{
+ friend gr_check_counting_s_sptr gr_make_check_counting_s (bool do_32bit);
+
+ enum state {
+ SEARCHING, // searching for synchronization
+ LOCKED // is locked
+ };
+
+ state d_state;
+ unsigned int d_history; // bitmask of decisions
+ unsigned short d_current_count;
+ unsigned int d_current_count_32bit;
+
+ long d_total_errors;
+ long d_total_shorts;
+ bool d_do_32bit;
+
+ gr_check_counting_s (bool do_32bit);
+
+ void enter_SEARCHING ();
+ void enter_LOCKED ();
+
+ void right (){
+ d_history = (d_history << 1) | 0x1;
+ }
+
+ void wrong (){
+ d_history = (d_history << 1) | 0x0;
+ d_total_errors++;
+ }
+
+ bool right_three_times () { return (d_history & 0x7) == 0x7; }
+ bool wrong_three_times () { return (d_history & 0x7) == 0x0; }
+
+ void log_error (unsigned short expected, unsigned short actual);
+ void log_error_32bit (unsigned int expected, unsigned int actual);
+
+ int check_32bit (int noutput_items, unsigned short * in);
+ int check_16bit (int noutput_items, unsigned short * in);
+
+ public:
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_CHECK_COUNTING_S_H */
diff --git a/gnuradio-core/src/lib/general/gr_check_counting_s.i b/gnuradio-core/src/lib/general/gr_check_counting_s.i
new file mode 100644
index 0000000000..f52f872408
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,check_counting_s)
+
+gr_check_counting_s_sptr gr_make_check_counting_s (bool do_32bit=false);
+
+class gr_check_counting_s : public gr_sync_block
+{
+ private:
+ gr_check_counting_s (bool do_32bit);
+};
diff --git a/gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.cc b/gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.cc
new file mode 100644
index 0000000000..72051cf5b5
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.cc
@@ -0,0 +1,169 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_check_lfsr_32k_s.h>
+#include <gr_io_signature.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+gr_check_lfsr_32k_s_sptr
+gr_make_check_lfsr_32k_s ()
+{
+ return gr_check_lfsr_32k_s_sptr (new gr_check_lfsr_32k_s ());
+}
+
+gr_check_lfsr_32k_s::gr_check_lfsr_32k_s ()
+ : gr_sync_block ("gr_check_lfsr_32k",
+ gr_make_io_signature (1, 1, sizeof (short)),
+ gr_make_io_signature (0, 0, 0)),
+ d_state(SEARCHING), d_history (0), d_ntotal (0), d_nright (0),
+ d_runlength (0), d_index(0)
+{
+ gri_lfsr_32k lfsr;
+
+ for (int i = 0; i < BUFSIZE; i++)
+ d_buffer[i] = lfsr.next_short ();
+
+ enter_SEARCHING ();
+}
+
+int
+gr_check_lfsr_32k_s::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ unsigned short *in = (unsigned short *) input_items[0];
+
+ for (int i = 0; i < noutput_items; i++){
+ unsigned short x = in[i];
+ unsigned short expected;
+
+ switch (d_state){
+
+ case MATCH0:
+ if (x == d_buffer[0])
+ enter_MATCH1 ();
+ break;
+
+ case MATCH1:
+ if (x == d_buffer[1])
+ enter_MATCH2 ();
+ else
+ enter_MATCH0 ();
+ break;
+
+ case MATCH2:
+ if (x == d_buffer[2])
+ enter_LOCKED ();
+ else
+ enter_MATCH0 ();
+ break;
+
+ case LOCKED:
+ expected = d_buffer[d_index];
+ d_index = d_index + 1;
+ if (d_index >= BUFSIZE)
+ d_index = 0;
+
+ if (x == expected)
+ right ();
+ else {
+ wrong ();
+ log_error (expected, x);
+ if (wrong_three_times ())
+ enter_SEARCHING ();
+ }
+ break;
+
+ default:
+ abort ();
+ }
+
+ d_ntotal++;
+ }
+
+ return noutput_items;
+}
+
+void
+gr_check_lfsr_32k_s::enter_SEARCHING ()
+{
+ d_state = SEARCHING;
+ wrong (); // reset history
+ wrong ();
+ wrong ();
+
+ d_runlength = 0;
+ d_index = 0; // reset LFSR to beginning
+
+ if (0)
+ fprintf (stdout, "gr_check_lfsr_32k: enter_SEARCHING at offset %8ld (0x%08lx)\n",
+ d_ntotal, d_ntotal);
+
+ enter_MATCH0 ();
+}
+
+void
+gr_check_lfsr_32k_s::enter_MATCH0 ()
+{
+ d_state = MATCH0;
+}
+
+void
+gr_check_lfsr_32k_s::enter_MATCH1 ()
+{
+ d_state = MATCH1;
+}
+
+void
+gr_check_lfsr_32k_s::enter_MATCH2 ()
+{
+ d_state = MATCH2;
+}
+
+void
+gr_check_lfsr_32k_s::enter_LOCKED ()
+{
+ d_state = LOCKED;
+ right (); // setup history
+ right ();
+ right ();
+
+ d_index = 3; // already matched first 3 items
+
+ if (0)
+ fprintf (stdout, "gr_check_lfsr_32k: enter_LOCKED at offset %8ld (0x%08lx)\n",
+ d_ntotal, d_ntotal);
+}
+
+void
+gr_check_lfsr_32k_s::log_error (unsigned short expected, unsigned short actual)
+{
+ if (0)
+ fprintf (stdout,
+ "gr_check_lfsr_32k: expected %5d (0x%04x) got %5d (0x%04x) offset %8ld (0x%08lx)\n",
+ expected, expected, actual, actual, d_ntotal, d_ntotal);
+}
diff --git a/gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.h b/gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.h
new file mode 100644
index 0000000000..4b7eb8a1b0
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.h
@@ -0,0 +1,102 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_CHECK_LFSR_32K_S_H
+#define INCLUDED_GR_CHECK_LFSR_32K_S_H
+
+#include <gr_sync_block.h>
+#include <gri_lfsr_32k.h>
+
+
+class gr_check_lfsr_32k_s;
+typedef boost::shared_ptr<gr_check_lfsr_32k_s> gr_check_lfsr_32k_s_sptr;
+
+gr_check_lfsr_32k_s_sptr gr_make_check_lfsr_32k_s ();
+
+/*!
+ * \brief sink that checks if its input stream consists of a lfsr_32k sequence.
+ * \ingroup sink
+ *
+ * This sink is typically used along with gr_lfsr_32k_source_s to test
+ * the USRP using its digital loopback mode.
+ */
+class gr_check_lfsr_32k_s : public gr_sync_block
+{
+ friend gr_check_lfsr_32k_s_sptr gr_make_check_lfsr_32k_s ();
+
+ enum state {
+ SEARCHING, // searching for synchronization
+ MATCH0,
+ MATCH1,
+ MATCH2,
+ LOCKED // is locked
+ };
+
+ state d_state;
+ unsigned int d_history; // bitmask of decisions
+
+ long d_ntotal; // total number of shorts
+ long d_nright; // # of correct shorts
+ long d_runlength; // # of correct shorts in a row
+
+ static const int BUFSIZE = 2048 - 1; // ensure pattern isn't packet aligned
+ int d_index;
+ unsigned short d_buffer[BUFSIZE];
+
+
+ gr_check_lfsr_32k_s ();
+
+ void enter_SEARCHING ();
+ void enter_MATCH0 ();
+ void enter_MATCH1 ();
+ void enter_MATCH2 ();
+ void enter_LOCKED ();
+
+ void right (){
+ d_history = (d_history << 1) | 0x1;
+ d_nright++;
+ d_runlength++;
+ }
+
+ void wrong (){
+ d_history = (d_history << 1) | 0x0;
+ d_runlength = 0;
+ }
+
+ bool right_three_times () { return (d_history & 0x7) == 0x7; }
+ bool wrong_three_times () { return (d_history & 0x7) == 0x0; }
+
+ void log_error (unsigned short expected, unsigned short actual);
+
+ public:
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ long ntotal () const { return d_ntotal; }
+ long nright () const { return d_nright; }
+ long runlength () const { return d_runlength; }
+
+};
+
+
+#endif /* INCLUDED_GR_CHECK_LFSR_32K_S_H */
diff --git a/gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.i b/gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.i
new file mode 100644
index 0000000000..422b7cd296
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,check_lfsr_32k_s)
+
+gr_check_lfsr_32k_s_sptr gr_make_check_lfsr_32k_s ();
+
+class gr_check_lfsr_32k_s : public gr_sync_block
+{
+ private:
+ gr_check_lfsr_32k_s ();
+
+public:
+ long ntotal () const;
+ long nright () const;
+ long runlength () const;
+};
diff --git a/gnuradio-core/src/lib/general/gr_chunks_to_symbols_XX.cc.t b/gnuradio-core/src/lib/general/gr_chunks_to_symbols_XX.cc.t
new file mode 100644
index 0000000000..a488733598
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_chunks_to_symbols_XX.cc.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <iostream>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D)
+{
+ return @SPTR_NAME@ (new @NAME@ (symbol_table,D));
+}
+
+@NAME@::@NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D)
+ : gr_sync_interpolator ("@BASE_NAME@",
+ gr_make_io_signature (1, -1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, -1, sizeof (@O_TYPE@)),
+ D),
+ d_D (D),
+ d_symbol_table (symbol_table)
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ assert (noutput_items % d_D == 0);
+ assert (input_items.size() == output_items.size());
+ int nstreams = input_items.size();
+
+ for (int m=0;m<nstreams;m++) {
+ const @I_TYPE@ *in = (@I_TYPE@ *) input_items[m];
+ @O_TYPE@ *out = (@O_TYPE@ *) output_items[m];
+
+ // per stream processing
+ for (int i = 0; i < noutput_items / d_D; i++){
+ assert (((unsigned int)in[i]*d_D) < d_symbol_table.size());
+ memcpy(out, &d_symbol_table[(unsigned int)in[i]*d_D], d_D*sizeof(@O_TYPE@));
+ out+=d_D;
+ }
+ // end of per stream processing
+
+ }
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_chunks_to_symbols_XX.h.t b/gnuradio-core/src/lib/general/gr_chunks_to_symbols_XX.h.t
new file mode 100644
index 0000000000..16763c9df7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_chunks_to_symbols_XX.h.t
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_interpolator.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D = 1);
+
+/*!
+ * \brief Map a stream of symbol indexes (unpacked bytes or shorts) to stream of float or complex onstellation points.in \p D dimensions (\p D = 1 by default)
+ * \ingroup block
+ *
+ * input: stream of @I_TYPE@; output: stream of @O_TYPE@
+ *
+ * out[n D + k] = symbol_table[in[n] D + k], k=0,1,...,D-1
+ *
+ * The combination of gr_packed_to_unpacked_XX followed by
+ * gr_chunks_to_symbols_XY handles the general case of mapping
+ * from a stream of bytes or shorts into arbitrary float
+ * or complex symbols.
+ *
+ * \sa gr_packed_to_unpacked_bb, gr_unpacked_to_packed_bb,
+ * \sa gr_packed_to_unpacked_ss, gr_unpacked_to_packed_ss,
+ * \sa gr_chunks_to_symbols_bf, gr_chunks_to_symbols_bc.
+ * \sa gr_chunks_to_symbols_sf, gr_chunks_to_symbols_sc.
+ */
+
+class @NAME@ : public gr_sync_interpolator
+{
+ friend @SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D);
+
+ int d_D;
+ std::vector<@O_TYPE@> d_symbol_table;
+ @NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D = 1);
+
+ public:
+ int D () const { return d_D; }
+ std::vector<@O_TYPE@> symbol_table () const { return d_symbol_table; }
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ bool check_topology(int ninputs, int noutputs) { return ninputs == noutputs; }
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_chunks_to_symbols_XX.i.t b/gnuradio-core/src/lib/general/gr_chunks_to_symbols_XX.i.t
new file mode 100644
index 0000000000..e67e480412
--- /dev/null
+++ b/gnuradio-core/src/lib/general/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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D = 1);
+
+class @NAME@ : public gr_sync_interpolator
+{
+private:
+ @NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D = 1);
+
+public:
+ int D () const { return d_D; }
+ std::vector<@O_TYPE@> symbol_table () const { return d_symbol_table; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_circular_file.cc b/gnuradio-core/src/lib/general/gr_circular_file.cc
new file mode 100644
index 0000000000..8aa8af08e4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_circular_file.cc
@@ -0,0 +1,194 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_circular_file.h>
+
+#include <unistd.h>
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include <algorithm>
+
+static const int HEADER_SIZE = 4096;
+static const int HEADER_MAGIC = 0xEB021026;
+
+static const int HD_MAGIC = 0;
+static const int HD_HEADER_SIZE = 1; // integer offsets into header
+static const int HD_BUFFER_SIZE = 2;
+static const int HD_BUFFER_BASE = 3;
+static const int HD_BUFFER_CURRENT = 4;
+
+gr_circular_file::gr_circular_file (const char *filename,
+ bool writable, int size)
+ : d_fd (-1), d_header (0), d_buffer (0), d_mapped_size (0), d_bytes_read (0)
+{
+ int mm_prot;
+ if (writable){
+#ifdef HAVE_MMAP
+ mm_prot = PROT_READ | PROT_WRITE;
+#endif
+ d_fd = open (filename, O_CREAT | O_RDWR | O_TRUNC, 0664);
+ if (d_fd < 0){
+ perror (filename);
+ exit (1);
+ }
+#ifdef HAVE_MMAP /* FIXME */
+ ftruncate (d_fd, size + HEADER_SIZE);
+#endif
+ }
+ else {
+#ifdef HAVE_MMAP
+ mm_prot = PROT_READ;
+#endif
+ d_fd = open (filename, O_RDONLY);
+ if (d_fd < 0){
+ perror (filename);
+ exit (1);
+ }
+ }
+
+ struct stat statbuf;
+ if (fstat (d_fd, &statbuf) < 0){
+ perror (filename);
+ exit (1);
+ }
+
+ if (statbuf.st_size < HEADER_SIZE){
+ fprintf (stderr, "%s: file too small to be circular buffer\n", filename);
+ exit (1);
+ }
+
+ d_mapped_size = statbuf.st_size;
+#ifdef HAVE_MMAP
+ void *p = mmap (0, d_mapped_size, mm_prot, MAP_SHARED, d_fd, 0);
+ if (p == MAP_FAILED){
+ perror ("gr_circular_file: mmap failed");
+ exit (1);
+ }
+
+ d_header = (int *) p;
+#else
+ perror ("gr_circular_file: mmap unsupported by this system");
+ exit (1);
+#endif
+
+ if (writable){ // init header
+
+ if (size < 0){
+ fprintf (stderr, "gr_circular_buffer: size must be > 0 when writable\n");
+ exit (1);
+ }
+
+ d_header[HD_MAGIC] = HEADER_MAGIC;
+ d_header[HD_HEADER_SIZE] = HEADER_SIZE;
+ d_header[HD_BUFFER_SIZE] = size;
+ d_header[HD_BUFFER_BASE] = HEADER_SIZE; // right after header
+ d_header[HD_BUFFER_CURRENT] = 0;
+ }
+
+ // sanity check (the asserts are a bit unforgiving...)
+
+ assert (d_header[HD_MAGIC] == HEADER_MAGIC);
+ assert (d_header[HD_HEADER_SIZE] == HEADER_SIZE);
+ assert (d_header[HD_BUFFER_SIZE] > 0);
+ assert (d_header[HD_BUFFER_BASE] >= d_header[HD_HEADER_SIZE]);
+ assert (d_header[HD_BUFFER_BASE] + d_header[HD_BUFFER_SIZE] <= d_mapped_size);
+ assert (d_header[HD_BUFFER_CURRENT] >= 0 &&
+ d_header[HD_BUFFER_CURRENT] < d_header[HD_BUFFER_SIZE]);
+
+ d_bytes_read = 0;
+ d_buffer = (unsigned char *) d_header + d_header[HD_BUFFER_BASE];
+}
+
+gr_circular_file::~gr_circular_file ()
+{
+#ifdef HAVE_MMAP
+ if (munmap ((char *) d_header, d_mapped_size) < 0){
+ perror ("gr_circular_file: munmap");
+ exit (1);
+ }
+#endif
+ close (d_fd);
+}
+
+bool
+gr_circular_file::write (void *vdata, int nbytes)
+{
+ unsigned char *data = (unsigned char *) vdata;
+ int buffer_size = d_header[HD_BUFFER_SIZE];
+ int buffer_current = d_header[HD_BUFFER_CURRENT];
+
+ while (nbytes > 0){
+ int n = std::min (nbytes, buffer_size - buffer_current);
+ memcpy (d_buffer + buffer_current, data, n);
+
+ buffer_current += n;
+ if (buffer_current >= buffer_size)
+ buffer_current = 0;
+
+ data += n;
+ nbytes -= n;
+ }
+
+ d_header[HD_BUFFER_CURRENT] = buffer_current;
+ return true;
+}
+
+int
+gr_circular_file::read (void *vdata, int nbytes)
+{
+ unsigned char *data = (unsigned char *) vdata;
+ int buffer_current = d_header[HD_BUFFER_CURRENT];
+ int buffer_size = d_header[HD_BUFFER_SIZE];
+ int total = 0;
+
+ nbytes = std::min (nbytes, buffer_size - d_bytes_read);
+
+ while (nbytes > 0){
+ int offset = (buffer_current + d_bytes_read) % buffer_size;
+ int n = std::min (nbytes, buffer_size - offset);
+ memcpy (data, d_buffer + offset, n);
+ data += n;
+ d_bytes_read += n;
+ total += n;
+ nbytes -= n;
+ }
+ return total;
+}
+
+void
+gr_circular_file::reset_read_pointer ()
+{
+ d_bytes_read = 0;
+}
diff --git a/gnuradio-core/src/lib/general/gr_circular_file.h b/gnuradio-core/src/lib/general/gr_circular_file.h
new file mode 100644
index 0000000000..33407457cc
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_circular_file.h
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GR_CIRCULAR_FILE_H_
+#define _GR_CIRCULAR_FILE_H_
+
+/*
+ * writes input data into a circular buffer on disk.
+ *
+ * the file contains a fixed header:
+ * 0x0000: int32 magic (0xEB021026)
+ * 0x0004: int32 size in bytes of header (constant 4096)
+ * 0x0008: int32 size in bytes of circular buffer (not including header)
+ * 0x000C: int32 file offset to beginning of circular buffer
+ * 0x0010: int32 byte offset from beginning of circular buffer to
+ * current start of data
+ *
+ */
+class gr_circular_file {
+ int d_fd;
+ int *d_header;
+ unsigned char *d_buffer;
+ int d_mapped_size;
+ int d_bytes_read;
+
+public:
+ gr_circular_file (const char *filename, bool writable = false, int size = 0);
+ ~gr_circular_file ();
+
+ bool write (void *data, int nbytes);
+
+ // returns # of bytes actually read or 0 if end of buffer, or -1 on error.
+ int read (void *data, int nbytes);
+
+ // reset read pointer to beginning of buffer.
+ void reset_read_pointer ();
+};
+
+#endif /* _GR_CIRCULAR_FILE_H_ */
diff --git a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.cc b/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.cc
new file mode 100644
index 0000000000..0d8c7f38d1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.cc
@@ -0,0 +1,182 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_io_signature.h>
+#include <gr_prefs.h>
+#include <gr_clock_recovery_mm_cc.h>
+#include <gri_mmse_fir_interpolator_cc.h>
+#include <stdexcept>
+
+// Public constructor
+
+
+gr_clock_recovery_mm_cc_sptr
+gr_make_clock_recovery_mm_cc(float omega, float gain_omega, float mu, float gain_mu,
+ float omega_relative_limit)
+{
+ return gr_clock_recovery_mm_cc_sptr (new gr_clock_recovery_mm_cc (omega,
+ gain_omega,
+ mu,
+ gain_mu,
+ omega_relative_limit));
+}
+
+gr_clock_recovery_mm_cc::gr_clock_recovery_mm_cc (float omega, float gain_omega, float mu,
+ float gain_mu, float omega_relative_limit)
+ : gr_block ("clock_recovery_mm_cc",
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex))),
+ d_mu (mu), d_omega(omega), d_gain_omega(gain_omega),
+ d_omega_relative_limit(omega_relative_limit),
+ d_gain_mu(gain_mu), d_last_sample(0), d_interp(new gri_mmse_fir_interpolator_cc()),
+ d_verbose(gr_prefs::singleton()->get_bool("clock_recovery_mm_cc", "verbose", false)),
+ d_p_2T(0), d_p_1T(0), d_p_0T(0), d_c_2T(0), d_c_1T(0), d_c_0T(0)
+{
+ if (omega <= 0.0)
+ throw std::out_of_range ("clock rate must be > 0");
+ if (gain_mu < 0 || gain_omega < 0)
+ throw std::out_of_range ("Gains must be non-negative");
+
+ set_omega(omega); // also sets min and max omega
+ set_relative_rate (1.0 / omega);
+ set_history(3); // ensure 2 extra input sample is available
+}
+
+gr_clock_recovery_mm_cc::~gr_clock_recovery_mm_cc ()
+{
+ delete d_interp;
+}
+
+void
+gr_clock_recovery_mm_cc::forecast(int noutput_items, gr_vector_int &ninput_items_required)
+{
+ unsigned ninputs = ninput_items_required.size();
+ for (unsigned i=0; i < ninputs; i++)
+ ninput_items_required[i] =
+ (int) ceil((noutput_items * d_omega) + d_interp->ntaps());
+}
+
+gr_complex
+gr_clock_recovery_mm_cc::slicer_0deg (gr_complex sample)
+{
+ float real=0, imag=0;
+
+ if(sample.real() > 0)
+ real = 1;
+ if(sample.imag() > 0)
+ imag = 1;
+ return gr_complex(real,imag);
+}
+
+gr_complex
+gr_clock_recovery_mm_cc::slicer_45deg (gr_complex sample)
+{
+ float real= -1, imag = -1;
+ if(sample.real() > 0)
+ real=1;
+ if(sample.imag() > 0)
+ imag = 1;
+ return gr_complex(real,imag);
+}
+
+/*
+ Modified Mueller and Muller clock recovery circuit
+ Based:
+ G. R. Danesfahani, T.G. Jeans, "Optimisation of modified Mueller and Muller
+ algorithm," Electronics Letters, Vol. 31, no. 13, 22 June 1995, pp. 1032 - 1033.
+*/
+
+static const int FUDGE = 16;
+
+int
+gr_clock_recovery_mm_cc::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *in = (const gr_complex *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ int ii = 0; // input index
+ int oo = 0; // output index
+ int ni = ninput_items[0] - d_interp->ntaps() - FUDGE; // don't use more input than this
+
+ assert(d_mu >= 0.0);
+ assert(d_mu <= 1.0);
+
+ float mm_val=0;
+ gr_complex u, x, y;
+
+ while(oo < noutput_items && ii < ni) {
+ d_p_2T = d_p_1T;
+ d_p_1T = d_p_0T;
+ d_p_0T = d_interp->interpolate (&in[ii], d_mu);
+
+ d_c_2T = d_c_1T;
+ d_c_1T = d_c_0T;
+ d_c_0T = slicer_0deg(d_p_0T);
+
+ x = (d_c_0T - d_c_2T) * conj(d_p_1T);
+ y = (d_p_0T - d_p_2T) * conj(d_c_1T);
+ u = y - x;
+ mm_val = u.real();
+ out[oo++] = d_p_0T;
+
+ // limit mm_val
+ if (mm_val > 1.0)
+ mm_val = 1.0;
+ else if (mm_val < -1.0)
+ mm_val = -1.0;
+
+ d_omega = d_omega + d_gain_omega * mm_val;
+ if (d_omega > d_max_omega)
+ d_omega = d_max_omega;
+ else if (d_omega < d_min_omega)
+ d_omega = d_min_omega;
+
+ d_mu = d_mu + d_omega + d_gain_mu * mm_val;
+ ii += (int)floor(d_mu);
+ d_mu -= floor(d_mu);
+
+ if(d_verbose) {
+ printf("%f\t%f\n", d_omega, d_mu);
+ }
+
+ if (ii < 0) // clamp it. This should only happen with bogus input
+ ii = 0;
+ }
+
+ if (ii > 0){
+ if (ii > ninput_items[0]){
+ fprintf(stderr, "gr_clock_recovery_mm_cc: ii > ninput_items[0] (%d > %d)\n",
+ ii, ninput_items[0]);
+ assert(0);
+ }
+ consume_each (ii);
+ }
+
+ return oo;
+}
diff --git a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.h b/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.h
new file mode 100644
index 0000000000..8a65ae4dd1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.h
@@ -0,0 +1,105 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_CLOCK_RECOVERY_MM_CC_H
+#define INCLUDED_GR_CLOCK_RECOVERY_MM_CC_H
+
+#include <gr_block.h>
+#include <gr_complex.h>
+
+class gri_mmse_fir_interpolator_cc;
+
+class gr_clock_recovery_mm_cc;
+typedef boost::shared_ptr<gr_clock_recovery_mm_cc> gr_clock_recovery_mm_cc_sptr;
+
+// public constructor
+gr_clock_recovery_mm_cc_sptr
+gr_make_clock_recovery_mm_cc (float omega, float gain_omega, float mu, float gain_mu,
+ float omega_relative_limit=0.001);
+
+/*!
+ * \brief Mueller and Müller (M&M) based clock recovery block with complex input, complex output.
+ * \ingroup block
+ *
+ * This implements the Mueller and Müller (M&M) discrete-time error-tracking synchronizer.
+ *
+ * See "Digital Communication Receivers: Synchronization, Channel
+ * Estimation and Signal Processing" by Heinrich Meyr, Marc Moeneclaey, & Stefan Fechtel.
+ * ISBN 0-471-50275-8.
+ */
+class gr_clock_recovery_mm_cc : public gr_block
+{
+ public:
+ ~gr_clock_recovery_mm_cc ();
+ void forecast(int noutput_items, gr_vector_int &ninput_items_required);
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ float mu() const { return d_mu;}
+ float omega() const { return d_omega;}
+ float gain_mu() const { return d_gain_mu;}
+ float gain_omega() const { return d_gain_omega;}
+ void set_verbose (bool verbose) { d_verbose = verbose; }
+
+ void set_gain_mu (float gain_mu) { d_gain_mu = gain_mu; }
+ void set_gain_omega (float gain_omega) { d_gain_omega = gain_omega; }
+ void set_mu (float mu) { d_mu = mu; }
+ void set_omega (float omega) {
+ d_omega = omega;
+ d_min_omega = omega*(1.0 - d_omega_relative_limit);
+ d_max_omega = omega*(1.0 + d_omega_relative_limit);
+ }
+
+protected:
+ gr_clock_recovery_mm_cc (float omega, float gain_omega, float mu, float gain_mu,
+ float omega_relative_limi);
+
+ private:
+ float d_mu;
+ float d_omega;
+ float d_gain_omega;
+ float d_min_omega; // minimum allowed omega
+ float d_max_omega; // maximum allowed omeg
+ float d_omega_relative_limit; // used to compute min and max omega
+ float d_gain_mu;
+ gr_complex d_last_sample;
+ gri_mmse_fir_interpolator_cc *d_interp;
+ bool d_verbose;
+
+ gr_complex d_p_2T;
+ gr_complex d_p_1T;
+ gr_complex d_p_0T;
+
+ gr_complex d_c_2T;
+ gr_complex d_c_1T;
+ gr_complex d_c_0T;
+
+ gr_complex slicer_0deg (gr_complex sample);
+ gr_complex slicer_45deg (gr_complex sample);
+
+ friend gr_clock_recovery_mm_cc_sptr
+ gr_make_clock_recovery_mm_cc (float omega, float gain_omega, float mu, float gain_mu,
+ float omega_relative_limit);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.i b/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.i
new file mode 100644
index 0000000000..4db01afff5
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.i
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,clock_recovery_mm_cc);
+
+gr_clock_recovery_mm_cc_sptr gr_make_clock_recovery_mm_cc (float omega, float gain_omega,
+ float mu, float gain_mu,
+ float omega_relative_limit);
+
+class gr_clock_recovery_mm_cc : public gr_sync_block
+{
+ private:
+ gr_clock_recovery_mm_cc (float omega, float gain_omega, float mu,
+ float gain_mu, float omega_relative_limit);
+
+public:
+ float mu() const { return d_mu;}
+ float omega() const { return d_omega;}
+ float gain_mu() const { return d_gain_mu;}
+ float gain_omega() const { return d_gain_omega;}
+
+ void set_gain_mu (float gain_mu) { d_gain_mu = gain_mu; }
+ void set_gain_omega (float gain_omega) { d_gain_omega = gain_omega; }
+ void set_mu (float omega) { d_mu = mu; }
+ void set_omega (float omega) { d_omega = omega;
+ d_min_omega = omega*(1.0 - d_omega_relative_limit);
+ d_max_omega = omega*(1.0 + d_omega_relative_limit);
+ }
+ void set_verbose (bool verbose) { d_verbose = verbose; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.cc b/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.cc
new file mode 100644
index 0000000000..1219df7bd3
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.cc
@@ -0,0 +1,140 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_io_signature.h>
+#include <gr_clock_recovery_mm_ff.h>
+#include <gri_mmse_fir_interpolator.h>
+#include <stdexcept>
+
+#define DEBUG_CR_MM_FF 0 // must be defined as 0 or 1
+
+// Public constructor
+
+gr_clock_recovery_mm_ff_sptr
+gr_make_clock_recovery_mm_ff(float omega, float gain_omega, float mu, float gain_mu,
+ float omega_relative_limit)
+{
+ return gr_clock_recovery_mm_ff_sptr (new gr_clock_recovery_mm_ff (omega,
+ gain_omega,
+ mu,
+ gain_mu,
+ omega_relative_limit));
+}
+
+gr_clock_recovery_mm_ff::gr_clock_recovery_mm_ff (float omega, float gain_omega, float mu, float gain_mu,
+ float omega_relative_limit)
+ : gr_block ("clock_recovery_mm_ff",
+ gr_make_io_signature (1, 1, sizeof (float)),
+ gr_make_io_signature (1, 1, sizeof (float))),
+ d_mu (mu), d_gain_omega(gain_omega), d_gain_mu(gain_mu),
+ d_last_sample(0), d_interp(new gri_mmse_fir_interpolator()),
+ d_logfile(0), d_omega_relative_limit(omega_relative_limit)
+{
+ if (omega < 1)
+ throw std::out_of_range ("clock rate must be > 0");
+ if (gain_mu < 0 || gain_omega < 0)
+ throw std::out_of_range ("Gains must be non-negative");
+
+ set_omega(omega); // also sets min and max omega
+ set_relative_rate (1.0 / omega);
+
+ if (DEBUG_CR_MM_FF)
+ d_logfile = fopen("cr_mm_ff.dat", "wb");
+}
+
+gr_clock_recovery_mm_ff::~gr_clock_recovery_mm_ff ()
+{
+ delete d_interp;
+
+ if (DEBUG_CR_MM_FF && d_logfile){
+ fclose(d_logfile);
+ d_logfile = 0;
+ }
+}
+
+void
+gr_clock_recovery_mm_ff::forecast(int noutput_items, gr_vector_int &ninput_items_required)
+{
+ unsigned ninputs = ninput_items_required.size();
+ for (unsigned i=0; i < ninputs; i++)
+ ninput_items_required[i] =
+ (int) ceil((noutput_items * d_omega) + d_interp->ntaps());
+}
+
+static inline float
+slice(float x)
+{
+ return x < 0 ? -1.0F : 1.0F;
+}
+
+/*
+ * This implements the Mueller and Müller (M&M) discrete-time error-tracking synchronizer.
+ *
+ * See "Digital Communication Receivers: Synchronization, Channel
+ * Estimation and Signal Processing" by Heinrich Meyr, Marc Moeneclaey, & Stefan Fechtel.
+ * ISBN 0-471-50275-8.
+ */
+int
+gr_clock_recovery_mm_ff::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+ float *out = (float *) output_items[0];
+
+ int ii = 0; // input index
+ int oo = 0; // output index
+ float mm_val;
+
+ while (oo < noutput_items){
+
+ // produce output sample
+ out[oo] = d_interp->interpolate (&in[ii], d_mu);
+ mm_val = slice(d_last_sample) * out[oo] - slice(out[oo]) * d_last_sample;
+ d_last_sample = out[oo];
+
+ d_omega = d_omega + d_gain_omega * mm_val;
+ if (d_omega > d_max_omega)
+ d_omega = d_max_omega;
+ else if (d_omega < d_min_omega)
+ d_omega = d_min_omega;
+
+ d_mu = d_mu + d_omega + d_gain_mu * mm_val;
+
+ ii += (int) floor(d_mu);
+ d_mu = d_mu - floor(d_mu);
+ oo++;
+
+ if (DEBUG_CR_MM_FF && d_logfile){
+ fwrite(&d_omega, sizeof(d_omega), 1, d_logfile);
+ }
+ }
+
+ consume_each (ii);
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.h b/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.h
new file mode 100644
index 0000000000..e970bcce81
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.h
@@ -0,0 +1,93 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_CLOCK_RECOVERY_MM_FF_H
+#define INCLUDED_GR_CLOCK_RECOVERY_MM_FF_H
+
+#include <gr_block.h>
+#include <stdio.h>
+
+class gri_mmse_fir_interpolator;
+
+class gr_clock_recovery_mm_ff;
+typedef boost::shared_ptr<gr_clock_recovery_mm_ff> gr_clock_recovery_mm_ff_sptr;
+
+// public constructor
+gr_clock_recovery_mm_ff_sptr
+gr_make_clock_recovery_mm_ff (float omega, float gain_omega, float mu, float gain_mu,
+ float omega_relative_limit=0.001);
+
+/*!
+ * \brief Mueller and Müller (M&M) based clock recovery block with float input, float output.
+ * \ingroup block
+ *
+ * This implements the Mueller and Müller (M&M) discrete-time error-tracking synchronizer.
+ *
+ * See "Digital Communication Receivers: Synchronization, Channel
+ * Estimation and Signal Processing" by Heinrich Meyr, Marc Moeneclaey, & Stefan Fechtel.
+ * ISBN 0-471-50275-8.
+ */
+class gr_clock_recovery_mm_ff : public gr_block
+{
+ public:
+ ~gr_clock_recovery_mm_ff ();
+ void forecast(int noutput_items, gr_vector_int &ninput_items_required);
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ float mu() const { return d_mu;}
+ float omega() const { return d_omega;}
+ float gain_mu() const { return d_gain_mu;}
+ float gain_omega() const { return d_gain_omega;}
+
+ void set_gain_mu (float gain_mu) { d_gain_mu = gain_mu; }
+ void set_gain_omega (float gain_omega) { d_gain_omega = gain_omega; }
+ void set_mu (float mu) { d_mu = mu; }
+ void set_omega (float omega){
+ d_omega = omega;
+ d_min_omega = omega*(1.0 - d_omega_relative_limit);
+ d_max_omega = omega*(1.0 + d_omega_relative_limit);
+ }
+
+protected:
+ gr_clock_recovery_mm_ff (float omega, float gain_omega, float mu, float gain_mu,
+ float omega_relative_limit);
+
+ private:
+ float d_mu; // fractional sample position [0.0, 1.0]
+ float d_omega; // nominal frequency
+ float d_min_omega; // minimum allowed omega
+ float d_max_omega; // maximum allowed omega
+ float d_gain_omega; // gain for adjusting omega
+ float d_gain_mu; // gain for adjusting mu
+ float d_last_sample;
+ gri_mmse_fir_interpolator *d_interp;
+ FILE *d_logfile;
+ float d_omega_relative_limit; // used to compute min and max omega
+
+ friend gr_clock_recovery_mm_ff_sptr
+ gr_make_clock_recovery_mm_ff (float omega, float gain_omega, float mu, float gain_mu,
+ float omega_relative_limit);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.i b/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.i
new file mode 100644
index 0000000000..5b7bd45d2c
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,clock_recovery_mm_ff);
+
+gr_clock_recovery_mm_ff_sptr gr_make_clock_recovery_mm_ff (float omega, float gain_omega,
+ float mu, float gain_mu,
+ float omega_relative_limit=0.001);
+
+class gr_clock_recovery_mm_ff : public gr_sync_block
+{
+ private:
+ gr_clock_recovery_mm_ff (float omega, float gain_omega, float mu, float gain_mu,
+ float omega_relative_limit);
+
+public:
+ float mu() const;
+ float omega() const;
+ float gain_mu() const;
+ float gain_omega() const;
+
+ void set_gain_mu (float gain_mu);
+ void set_gain_omega (float gain_omega);
+ void set_mu (float omega);
+ void set_omega (float omega);
+};
diff --git a/gnuradio-core/src/lib/general/gr_complex_to_interleaved_short.cc b/gnuradio-core/src/lib/general/gr_complex_to_interleaved_short.cc
new file mode 100644
index 0000000000..65fbbe93b2
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_complex_to_interleaved_short.cc
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_complex_to_interleaved_short.h>
+#include <gr_io_signature.h>
+#include <math.h>
+
+gr_complex_to_interleaved_short_sptr
+gr_make_complex_to_interleaved_short ()
+{
+ return gr_complex_to_interleaved_short_sptr (new gr_complex_to_interleaved_short ());
+}
+
+gr_complex_to_interleaved_short::gr_complex_to_interleaved_short ()
+ : gr_sync_interpolator ("gr_complex_to_interleaved_short",
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, sizeof (short)),
+ 2)
+{
+}
+
+int
+gr_complex_to_interleaved_short::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *in = (const gr_complex *) input_items[0];
+ short *out = (short *) output_items[0];
+
+ for (int i = 0; i < noutput_items/2; i++){
+ *out++ = (short) lrintf(in[i].real()); // FIXME saturate?
+ *out++ = (short) lrintf(in[i].imag());
+ }
+
+ return noutput_items;
+}
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_complex_to_interleaved_short.h b/gnuradio-core/src/lib/general/gr_complex_to_interleaved_short.h
new file mode 100644
index 0000000000..1afca560af
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_complex_to_interleaved_short.h
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_COMPLEX_TO_INTERLEAVED_SHORT_H
+#define INCLUDED_GR_COMPLEX_TO_INTERLEAVED_SHORT_H
+
+#include <gr_sync_interpolator.h>
+
+class gr_complex_to_interleaved_short;
+typedef boost::shared_ptr<gr_complex_to_interleaved_short>
+ gr_complex_to_interleaved_short_sptr;
+
+gr_complex_to_interleaved_short_sptr
+gr_make_complex_to_interleaved_short ();
+
+/*!
+ * \brief Convert stream of complex to a stream of interleaved shorts
+ * \ingroup converter
+ */
+
+class gr_complex_to_interleaved_short : public gr_sync_interpolator
+{
+ friend gr_complex_to_interleaved_short_sptr gr_make_complex_to_interleaved_short ();
+ gr_complex_to_interleaved_short ();
+
+ public:
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_COMPLEX_TO_INTERLEAVED_SHORT_H */
diff --git a/gnuradio-core/src/lib/general/gr_complex_to_interleaved_short.i b/gnuradio-core/src/lib/general/gr_complex_to_interleaved_short.i
new file mode 100644
index 0000000000..1b4b6baa03
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,complex_to_interleaved_short)
+
+gr_complex_to_interleaved_short_sptr gr_make_complex_to_interleaved_short ();
+
+class gr_complex_to_interleaved_short : public gr_sync_interpolator
+{
+ gr_complex_to_interleaved_short ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_complex_to_xxx.cc b/gnuradio-core/src/lib/general/gr_complex_to_xxx.cc
new file mode 100644
index 0000000000..727f44f073
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_complex_to_xxx.cc
@@ -0,0 +1,199 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_complex_to_xxx.h>
+#include <gr_io_signature.h>
+
+// ----------------------------------------------------------------
+
+gr_complex_to_float_sptr
+gr_make_complex_to_float (unsigned int vlen)
+{
+ return gr_complex_to_float_sptr (new gr_complex_to_float (vlen));
+}
+
+gr_complex_to_float::gr_complex_to_float (unsigned int vlen)
+ : gr_sync_block ("complex_to_float",
+ gr_make_io_signature (1, 1, sizeof (gr_complex) * vlen),
+ gr_make_io_signature (1, 2, sizeof (float) * vlen)),
+ d_vlen(vlen)
+{
+}
+
+int
+gr_complex_to_float::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *in = (const gr_complex *) input_items[0];
+ float *out0 = (float *) output_items[0];
+ float *out1 = (float *) output_items[1];
+ int noi = noutput_items * d_vlen;
+
+ switch (output_items.size ()){
+ case 1:
+ for (int i = 0; i < noi; i++){
+ out0[i] = in[i].real ();
+ }
+ break;
+
+ case 2:
+ for (int i = 0; i < noi; i++){
+ out0[i] = in[i].real ();
+ out1[i] = in[i].imag ();
+ }
+ break;
+
+ default:
+ abort ();
+ }
+
+ return noutput_items;
+}
+
+// ----------------------------------------------------------------
+
+gr_complex_to_real_sptr
+gr_make_complex_to_real (unsigned int vlen)
+{
+ return gr_complex_to_real_sptr (new gr_complex_to_real (vlen));
+}
+
+gr_complex_to_real::gr_complex_to_real (unsigned int vlen)
+ : gr_sync_block ("complex_to_real",
+ gr_make_io_signature (1, 1, sizeof (gr_complex) * vlen),
+ gr_make_io_signature (1, 1, sizeof (float) * vlen)),
+ d_vlen(vlen)
+{
+}
+
+int
+gr_complex_to_real::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *in = (const gr_complex *) input_items[0];
+ float *out = (float *) output_items[0];
+ int noi = noutput_items * d_vlen;
+
+ for (int i = 0; i < noi; i++){
+ out[i] = in[i].real ();
+ }
+ return noutput_items;
+}
+
+// ----------------------------------------------------------------
+
+gr_complex_to_imag_sptr
+gr_make_complex_to_imag (unsigned int vlen)
+{
+ return gr_complex_to_imag_sptr (new gr_complex_to_imag (vlen));
+}
+
+gr_complex_to_imag::gr_complex_to_imag (unsigned int vlen)
+ : gr_sync_block ("complex_to_imag",
+ gr_make_io_signature (1, 1, sizeof (gr_complex) * vlen),
+ gr_make_io_signature (1, 1, sizeof (float) * vlen)),
+ d_vlen(vlen)
+{
+}
+
+int
+gr_complex_to_imag::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *in = (const gr_complex *) input_items[0];
+ float *out = (float *) output_items[0];
+ int noi = noutput_items * d_vlen;
+
+ for (int i = 0; i < noi; i++){
+ out[i] = in[i].imag ();
+ }
+ return noutput_items;
+}
+
+// ----------------------------------------------------------------
+
+gr_complex_to_mag_sptr
+gr_make_complex_to_mag (unsigned int vlen)
+{
+ return gr_complex_to_mag_sptr (new gr_complex_to_mag (vlen));
+}
+
+gr_complex_to_mag::gr_complex_to_mag (unsigned int vlen)
+ : gr_sync_block ("complex_to_mag",
+ gr_make_io_signature (1, 1, sizeof (gr_complex) * vlen),
+ gr_make_io_signature (1, 1, sizeof (float) * vlen)),
+ d_vlen(vlen)
+{
+}
+
+int
+gr_complex_to_mag::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *in = (const gr_complex *) input_items[0];
+ float *out = (float *) output_items[0];
+ int noi = noutput_items * d_vlen;
+
+ for (int i = 0; i < noi; i++){
+ out[i] = std::abs (in[i]);
+ }
+ return noutput_items;
+}
+
+// ----------------------------------------------------------------
+
+gr_complex_to_arg_sptr
+gr_make_complex_to_arg (unsigned int vlen)
+{
+ return gr_complex_to_arg_sptr (new gr_complex_to_arg (vlen));
+}
+
+gr_complex_to_arg::gr_complex_to_arg (unsigned int vlen)
+ : gr_sync_block ("complex_to_arg",
+ gr_make_io_signature (1, 1, sizeof (gr_complex) * vlen),
+ gr_make_io_signature (1, 1, sizeof (float) * vlen)),
+ d_vlen(vlen)
+{
+}
+
+int
+gr_complex_to_arg::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *in = (const gr_complex *) input_items[0];
+ float *out = (float *) output_items[0];
+ int noi = noutput_items * d_vlen;
+
+ for (int i = 0; i < noi; i++){
+ out[i] = std::arg (in[i]);
+ }
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_complex_to_xxx.h b/gnuradio-core/src/lib/general/gr_complex_to_xxx.h
new file mode 100644
index 0000000000..02a9fc8fd9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_complex_to_xxx.h
@@ -0,0 +1,137 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_COMPLEX_TO_XXX_H
+#define INCLUDED_GR_COMPLEX_TO_XXX_H
+
+#include <gr_sync_block.h>
+#include <gr_complex.h>
+
+class gr_complex_to_float;
+class gr_complex_to_real;
+class gr_complex_to_imag;
+class gr_complex_to_mag;
+class gr_complex_to_arg;
+
+typedef boost::shared_ptr<gr_complex_to_float> gr_complex_to_float_sptr;
+typedef boost::shared_ptr<gr_complex_to_real> gr_complex_to_real_sptr;
+typedef boost::shared_ptr<gr_complex_to_imag> gr_complex_to_imag_sptr;
+typedef boost::shared_ptr<gr_complex_to_mag> gr_complex_to_mag_sptr;
+typedef boost::shared_ptr<gr_complex_to_arg> gr_complex_to_arg_sptr;
+
+gr_complex_to_float_sptr gr_make_complex_to_float (unsigned int vlen=1);
+gr_complex_to_real_sptr gr_make_complex_to_real (unsigned int vlen=1);
+gr_complex_to_imag_sptr gr_make_complex_to_imag (unsigned int vlen=1);
+gr_complex_to_mag_sptr gr_make_complex_to_mag (unsigned int vlen=1);
+gr_complex_to_arg_sptr gr_make_complex_to_arg (unsigned int vlen=1);
+
+/*!
+ * \brief convert a stream of gr_complex to 1 or 2 streams of float
+ * \ingroup converter
+ * \param vlen vector len (default 1)
+ */
+class gr_complex_to_float : public gr_sync_block
+{
+ friend gr_complex_to_float_sptr gr_make_complex_to_float (unsigned int vlen);
+ gr_complex_to_float (unsigned int vlen);
+
+ unsigned int d_vlen;
+
+ public:
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+/*!
+ * \brief complex in, real out (float)
+ * \ingroup converter
+ * \param vlen vector len (default 1)
+ */
+class gr_complex_to_real : public gr_sync_block
+{
+ friend gr_complex_to_real_sptr gr_make_complex_to_real (unsigned int vlen);
+ gr_complex_to_real (unsigned int vlen);
+
+ unsigned int d_vlen;
+
+ public:
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+/*!
+ * \brief complex in, imaginary out (float)
+ * \ingroup converter
+ * \param vlen vector len (default 1)
+ */
+class gr_complex_to_imag : public gr_sync_block
+{
+ friend gr_complex_to_imag_sptr gr_make_complex_to_imag (unsigned int vlen);
+ gr_complex_to_imag (unsigned int vlen);
+
+ unsigned int d_vlen;
+
+ public:
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+/*!
+ * \brief complex in, magnitude out (float)
+ * \ingroup converter
+ * \param vlen vector len (default 1)
+ */
+class gr_complex_to_mag : public gr_sync_block
+{
+ friend gr_complex_to_mag_sptr gr_make_complex_to_mag (unsigned int vlen);
+ gr_complex_to_mag (unsigned int vlen);
+
+ unsigned int d_vlen;
+
+ public:
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+/*!
+ * \brief complex in, angle out (float)
+ * \ingroup converter
+ * \param vlen vector len (default 1)
+ */
+class gr_complex_to_arg : public gr_sync_block
+{
+ friend gr_complex_to_arg_sptr gr_make_complex_to_arg (unsigned int vlen);
+ gr_complex_to_arg (unsigned int vlen);
+
+ unsigned int d_vlen;
+
+ public:
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_COMPLEX_TO_XXX_H */
diff --git a/gnuradio-core/src/lib/general/gr_complex_to_xxx.i b/gnuradio-core/src/lib/general/gr_complex_to_xxx.i
new file mode 100644
index 0000000000..06f1020a02
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_complex_to_xxx.i
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,complex_to_float);
+gr_complex_to_float_sptr gr_make_complex_to_float (unsigned int vlen=1);
+class gr_complex_to_float : public gr_sync_block
+{
+ gr_complex_to_float (unsigned int vlen);
+};
+
+GR_SWIG_BLOCK_MAGIC(gr,complex_to_real);
+gr_complex_to_real_sptr gr_make_complex_to_real (unsigned int vlen=1);
+class gr_complex_to_real : public gr_sync_block
+{
+ gr_complex_to_real (unsigned int vlen);
+};
+
+GR_SWIG_BLOCK_MAGIC(gr,complex_to_imag);
+gr_complex_to_imag_sptr gr_make_complex_to_imag (unsigned int vlen=1);
+class gr_complex_to_imag : public gr_sync_block
+{
+ gr_complex_to_imag (unsigned int vlen);
+}
+ ;
+GR_SWIG_BLOCK_MAGIC(gr,complex_to_mag);
+gr_complex_to_mag_sptr gr_make_complex_to_mag (unsigned int vlen=1);
+class gr_complex_to_mag : public gr_sync_block
+{
+ gr_complex_to_mag (unsigned int vlen);
+};
+
+GR_SWIG_BLOCK_MAGIC(gr,complex_to_arg);
+gr_complex_to_arg_sptr gr_make_complex_to_arg (unsigned int vlen=1);
+class gr_complex_to_arg : public gr_sync_block
+{
+ gr_complex_to_arg (unsigned int vlen);
+};
+
diff --git a/gnuradio-core/src/lib/general/gr_conjugate_cc.cc b/gnuradio-core/src/lib/general/gr_conjugate_cc.cc
new file mode 100644
index 0000000000..50e25efafe
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_conjugate_cc.cc
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// WARNING: this file is machine generated. Edits will be over written
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_conjugate_cc.h>
+#include <gr_io_signature.h>
+
+gr_conjugate_cc_sptr
+gr_make_conjugate_cc ()
+{
+ return gr_conjugate_cc_sptr (new gr_conjugate_cc ());
+}
+
+gr_conjugate_cc::gr_conjugate_cc ()
+ : gr_sync_block ("conjugate_cc",
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex)))
+{
+}
+
+int
+gr_conjugate_cc::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ gr_complex *iptr = (gr_complex *) input_items[0];
+ gr_complex *optr = (gr_complex *) output_items[0];
+
+ int size = noutput_items;
+
+ while (size >= 8){
+ *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
+ *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
+ *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
+ *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
+ *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
+ *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
+ *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
+ *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
+ size -= 8;
+ }
+
+ while (size-- > 0)
+ *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_conjugate_cc.h b/gnuradio-core/src/lib/general/gr_conjugate_cc.h
new file mode 100644
index 0000000000..f1551b863b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_conjugate_cc.h
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// WARNING: this file is machine generated. Edits will be over written
+
+#ifndef INCLUDED_GR_CONJUGATE_CC_H
+#define INCLUDED_GR_CONJUGATE_CC_H
+
+#include <gr_sync_block.h>
+
+class gr_conjugate_cc;
+typedef boost::shared_ptr<gr_conjugate_cc> gr_conjugate_cc_sptr;
+
+gr_conjugate_cc_sptr gr_make_conjugate_cc ();
+
+/*!
+ * \brief output = complex conjugate of input
+ * \ingroup block
+ */
+class gr_conjugate_cc : public gr_sync_block
+{
+ friend gr_conjugate_cc_sptr gr_make_conjugate_cc ();
+
+ gr_conjugate_cc ();
+
+ public:
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_conjugate_cc.i b/gnuradio-core/src/lib/general/gr_conjugate_cc.i
new file mode 100644
index 0000000000..efafa84c70
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// WARNING: this file is machine generated. Edits will be over written
+
+GR_SWIG_BLOCK_MAGIC(gr,conjugate_cc)
+
+gr_conjugate_cc_sptr gr_make_conjugate_cc ();
+
+class gr_conjugate_cc : public gr_sync_block
+{
+ private:
+ gr_conjugate_cc ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_constellation_decoder_cb.cc b/gnuradio-core/src/lib/general/gr_constellation_decoder_cb.cc
new file mode 100644
index 0000000000..5b4f719d06
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_constellation_decoder_cb.cc
@@ -0,0 +1,113 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_constellation_decoder_cb.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+#include <iostream>
+using std::cout;
+using std::endl;
+
+static const bool compute_EVM = false;
+
+gr_constellation_decoder_cb_sptr
+gr_make_constellation_decoder_cb (const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out)
+{
+ return gr_constellation_decoder_cb_sptr
+ (new gr_constellation_decoder_cb(sym_position, sym_value_out));
+}
+
+gr_constellation_decoder_cb::
+gr_constellation_decoder_cb (const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out)
+ : gr_sync_block ("constellation_decoder_cb",
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, sizeof (unsigned char)))
+{
+ if (!set_constellation(sym_position,sym_value_out))
+ throw std::invalid_argument("constellation_decoder_cb");
+}
+
+
+gr_constellation_decoder_cb::~gr_constellation_decoder_cb(){}
+
+
+bool
+gr_constellation_decoder_cb::set_constellation(const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out)
+{
+ if (sym_position.size() != sym_value_out.size())
+ return false;
+
+ if (sym_position.size()<1)
+ return false;
+
+ d_sym_position = sym_position;
+ d_sym_value_out = sym_value_out;
+ return true;
+}
+
+
+int
+gr_constellation_decoder_cb::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ gr_complex const *in = (const gr_complex *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+ unsigned int table_size = d_sym_value_out.size();
+ unsigned int min_index = 0;
+ float min_euclid_dist = 0;
+ float euclid_dist = 0;
+ double total_error = 0;
+
+ for(int i = 0; i < noutput_items; i++){
+ min_euclid_dist = norm(in[i] - d_sym_position[0]);
+ min_index = 0;
+ for (unsigned int j = 1; j < table_size; j++){
+ euclid_dist = norm(in[i] - d_sym_position[j]);
+ if (euclid_dist < min_euclid_dist){
+ min_euclid_dist = euclid_dist;
+ min_index = j;
+ }
+ }
+
+ out[i] = d_sym_value_out[min_index];
+
+ if (compute_EVM)
+ total_error += sqrtf(min_euclid_dist);
+ }
+
+ if (compute_EVM){
+ double mean = total_error / noutput_items;
+ double rms = sqrt(mean * mean);
+ fprintf(stderr, "EVM = %8.4f\n", rms);
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_constellation_decoder_cb.h b/gnuradio-core/src/lib/general/gr_constellation_decoder_cb.h
new file mode 100644
index 0000000000..2cc16c57db
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_constellation_decoder_cb.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_CONSTELLATION_DECODER_CB_H
+#define INCLUDED_GR_CONSTELLATION_DECODER_CB_H
+
+#include <gr_sync_block.h>
+#include <vector>
+
+class gr_constellation_decoder_cb;
+typedef boost::shared_ptr<gr_constellation_decoder_cb> gr_constellation_decoder_cb_sptr;
+
+gr_constellation_decoder_cb_sptr
+ gr_make_constellation_decoder_cb (const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out);
+
+
+class gr_constellation_decoder_cb : public gr_sync_block
+{
+
+ private:
+ std::vector<gr_complex> d_sym_position;
+ std::vector<unsigned char> d_sym_value_out;
+
+ friend gr_constellation_decoder_cb_sptr
+ gr_make_constellation_decoder_cb (const std::vector<gr_complex> &sym_position, const std::vector<unsigned char> &sym_value_out);
+
+ gr_constellation_decoder_cb (const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out); //constructor
+
+ public:
+ bool set_constellation(const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out);
+
+ ~gr_constellation_decoder_cb(); //destructor
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_constellation_decoder_cb.i b/gnuradio-core/src/lib/general/gr_constellation_decoder_cb.i
new file mode 100644
index 0000000000..ba1e38f6b4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_constellation_decoder_cb.i
@@ -0,0 +1,43 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,constellation_decoder_cb)
+
+gr_constellation_decoder_cb_sptr
+ gr_make_constellation_decoder_cb (const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out);
+
+class gr_constellation_decoder_cb : public gr_sync_block
+{
+ private:
+ gr_constellation_decoder_cb (const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out);
+
+ friend gr_constellation_decoder_cb_sptr
+ gr_make_constellation_decoder_cb (const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out);
+
+ public:
+ int set_constellation(const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out);
+ ~gr_constellation_decoder_cb();
+};
diff --git a/gnuradio-core/src/lib/general/gr_correlate_access_code_bb.cc b/gnuradio-core/src/lib/general/gr_correlate_access_code_bb.cc
new file mode 100644
index 0000000000..0f25986078
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_correlate_access_code_bb.cc
@@ -0,0 +1,129 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_correlate_access_code_bb.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <gr_count_bits.h>
+
+#define VERBOSE 0
+
+
+gr_correlate_access_code_bb_sptr
+gr_make_correlate_access_code_bb (const std::string &access_code, int threshold)
+{
+ return gr_correlate_access_code_bb_sptr (new gr_correlate_access_code_bb (access_code, threshold));
+}
+
+
+gr_correlate_access_code_bb::gr_correlate_access_code_bb (
+ const std::string &access_code, int threshold)
+ : gr_sync_block ("correlate_access_code_bb",
+ gr_make_io_signature (1, 1, sizeof(char)),
+ gr_make_io_signature (1, 1, sizeof(char))),
+ d_data_reg(0), d_flag_reg(0), d_flag_bit(0), d_mask(0),
+ d_threshold(threshold), d_flip(0)
+
+{
+ if (!set_access_code(access_code)){
+ fprintf(stderr, "gr_correlate_access_code_bb: access_code is > 64 bits\n");
+ throw std::out_of_range ("access_code is > 64 bits");
+ }
+}
+
+gr_correlate_access_code_bb::~gr_correlate_access_code_bb ()
+{
+}
+
+bool
+gr_correlate_access_code_bb::set_access_code(
+ const std::string &access_code)
+{
+ unsigned len = access_code.length(); // # of bytes in string
+ if (len > 64)
+ return false;
+
+ // set len top bits to 1.
+ d_mask = ((~0ULL) >> (64 - len)) << (64 - len);
+
+ d_flag_bit = 1LL << (64 - len); // Where we or-in new flag values.
+ // new data always goes in 0x0000000000000001
+ d_access_code = 0;
+ for (unsigned i=0; i < 64; i++){
+ d_access_code <<= 1;
+ if (i < len)
+ d_access_code |= access_code[i] & 1; // look at LSB only
+ }
+
+ return true;
+}
+
+int
+gr_correlate_access_code_bb::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+
+ for (int i = 0; i < noutput_items; i++){
+
+ // compute output value
+ unsigned int t = 0;
+
+ t |= d_flip ^ (((d_data_reg >> 63) & 0x1) << 0);
+ t |= ((d_flag_reg >> 63) & 0x1) << 1; // flag bit
+ out[i] = t;
+
+ // compute hamming distance between desired access code and current data
+ unsigned long long wrong_bits = 0;
+ unsigned int nwrong = d_threshold+1;
+ int new_flag = 0;
+
+ wrong_bits = (d_data_reg ^ d_access_code) & d_mask;
+ nwrong = gr_count_bits64(wrong_bits);
+
+ // test for access code with up to threshold errors or its compelement
+ new_flag = (nwrong <= d_threshold) || (nwrong >= (64-d_threshold));
+
+#if 0
+ if(new_flag) {
+ printf("%llx ==> %llx : d_flip=%u\n", d_access_code, d_data_reg, d_flip);
+ }
+#endif
+
+ // shift in new data and new flag
+ d_data_reg = (d_data_reg << 1) | (in[i] & 0x1);
+ d_flag_reg = (d_flag_reg << 1);
+ if (new_flag) {
+ d_flag_reg |= d_flag_bit;
+ d_flip = nwrong >= (64-d_threshold); // flip bits if this is true
+ }
+ }
+
+ return noutput_items;
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_correlate_access_code_bb.h b/gnuradio-core/src/lib/general/gr_correlate_access_code_bb.h
new file mode 100644
index 0000000000..519258cae6
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_correlate_access_code_bb.h
@@ -0,0 +1,85 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_CORRELATE_ACCESS_CODE_BB_H
+#define INCLUDED_GR_CORRELATE_ACCESS_CODE_BB_H
+
+#include <gr_sync_block.h>
+#include <string>
+
+class gr_correlate_access_code_bb;
+typedef boost::shared_ptr<gr_correlate_access_code_bb> gr_correlate_access_code_bb_sptr;
+
+/*!
+ * \param access_code is represented with 1 byte per bit, e.g., "010101010111000100"
+ * \param threshold maximum number of bits that may be wrong
+ */
+gr_correlate_access_code_bb_sptr
+gr_make_correlate_access_code_bb (const std::string &access_code, int threshold);
+
+/*!
+ * \brief Examine input for specified access code, one bit at a time.
+ * \ingroup block
+ *
+ * input: stream of bits, 1 bit per input byte (data in LSB)
+ * output: stream of bits, 2 bits per output byte (data in LSB, flag in next higher bit)
+ *
+ * Each output byte contains two valid bits, the data bit, and the
+ * flag bit. The LSB (bit 0) is the data bit, and is the original
+ * input data, delayed 64 bits. Bit 1 is the
+ * flag bit and is 1 if the corresponding data bit is the first data
+ * bit following the access code. Otherwise the flag bit is 0.
+ */
+class gr_correlate_access_code_bb : public gr_sync_block
+{
+ friend gr_correlate_access_code_bb_sptr
+ gr_make_correlate_access_code_bb (const std::string &access_code, int threshold);
+ private:
+ unsigned long long d_access_code; // access code to locate start of packet
+ // access code is left justified in the word
+ unsigned long long d_data_reg; // used to look for access_code
+ unsigned long long d_flag_reg; // keep track of decisions
+ unsigned long long d_flag_bit; // mask containing 1 bit which is location of new flag
+ unsigned long long d_mask; // masks access_code bits (top N bits are set where
+ // N is the number of bits in the access code)
+ unsigned int d_threshold; // how many bits may be wrong in sync vector
+ unsigned int d_flip; // flip bits if 180 degress out of sync
+
+
+ protected:
+ gr_correlate_access_code_bb(const std::string &access_code, int threshold);
+
+ public:
+ ~gr_correlate_access_code_bb();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+
+ /*!
+ * \param access_code is represented with 1 byte per bit, e.g., "010101010111000100"
+ */
+ bool set_access_code (const std::string &access_code);
+};
+
+#endif /* INCLUDED_GR_CORRELATE_ACCESS_CODE_BB_H */
diff --git a/gnuradio-core/src/lib/general/gr_correlate_access_code_bb.i b/gnuradio-core/src/lib/general/gr_correlate_access_code_bb.i
new file mode 100644
index 0000000000..688f3f694b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_correlate_access_code_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,correlate_access_code_bb);
+
+/*!
+ * \param access_code is represented with 1 byte per bit, e.g., "010101010111000100"
+ * \param threshold maximum number of bits that may be wrong
+ */
+gr_correlate_access_code_bb_sptr
+gr_make_correlate_access_code_bb (const std::string &access_code, int threshold)
+ throw(std::out_of_range);
+
+/*!
+ * \brief Examine input for specified access code, one bit at a time.
+ * \ingroup block
+ *
+ * input: stream of bits, 1 bit per input byte (data in LSB)
+ * output: stream of bits, 2 bits per output byte (data in LSB, flag in next higher bit)
+ *
+ * Each output byte contains two valid bits, the data bit, and the
+ * flag bit. The LSB (bit 0) is the data bit, and is the original
+ * input data, delayed 64 bits. Bit 1 is the
+ * flag bit and is 1 if the corresponding data bit is the first data
+ * bit following the access code. Otherwise the flag bit is 0.
+ */
+class gr_correlate_access_code_bb : public gr_sync_block
+{
+ friend gr_correlate_access_code_bb_sptr
+ gr_make_correlate_access_code_bb (const std::string &access_code, int threshold);
+ protected:
+ gr_correlate_access_code_bb(const std::string &access_code, int threshold);
+
+ public:
+ ~gr_correlate_access_code_bb();
+
+ /*!
+ * \param access_code is represented with 1 byte per bit, e.g., "010101010111000100"
+ */
+ bool set_access_code (const std::string &access_code);
+};
diff --git a/gnuradio-core/src/lib/general/gr_costas_loop_cc.cc b/gnuradio-core/src/lib/general/gr_costas_loop_cc.cc
new file mode 100644
index 0000000000..4ad627f029
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_costas_loop_cc.cc
@@ -0,0 +1,118 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_costas_loop_cc.h>
+#include <gr_io_signature.h>
+#include <gr_expj.h>
+#include <gr_sincos.h>
+#include <math.h>
+
+#define M_TWOPI (2*M_PI)
+
+gr_costas_loop_cc_sptr
+gr_make_costas_loop_cc (float alpha, float beta,
+ float max_freq, float min_freq,
+ int order
+ ) throw (std::invalid_argument)
+{
+ return gr_costas_loop_cc_sptr (new gr_costas_loop_cc (alpha, beta,
+ max_freq, min_freq,
+ order));
+}
+
+gr_costas_loop_cc::gr_costas_loop_cc (float alpha, float beta,
+ float max_freq, float min_freq,
+ int order
+ ) throw (std::invalid_argument)
+ : gr_sync_block ("costas_loop_cc",
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex))),
+ d_alpha(alpha), d_beta(beta),
+ d_max_freq(max_freq), d_min_freq(min_freq),
+ d_phase(0), d_freq((max_freq+min_freq)/2),
+ d_order(order), d_phase_detector(0)
+{
+ switch(d_order) {
+ case 2:
+ d_phase_detector = &gr_costas_loop_cc::phase_detector_2;
+ break;
+
+ case 4:
+ d_phase_detector = &gr_costas_loop_cc::phase_detector_4;
+ break;
+
+ default:
+ throw std::invalid_argument("order must be 2 or 4");
+ break;
+ }
+}
+
+
+float
+gr_costas_loop_cc::phase_detector_4(gr_complex sample) const
+{
+
+ return ((sample.real()>0 ? 1.0 : -1.0) * sample.imag() -
+ (sample.imag()>0 ? 1.0 : -1.0) * sample.real());
+}
+
+float
+gr_costas_loop_cc::phase_detector_2(gr_complex sample) const
+{
+ return (sample.real()*sample.imag());
+}
+
+int
+gr_costas_loop_cc::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *iptr = (gr_complex *) input_items[0];
+ gr_complex *optr = (gr_complex *) output_items[0];
+
+ float error;
+ gr_complex nco_out;
+
+ for (int i = 0; i < noutput_items; i++){
+ nco_out = gr_expj(-d_phase);
+ optr[i] = iptr[i] * nco_out;
+
+ error = (*this.*d_phase_detector)(optr[i]);
+
+ d_freq = d_freq + d_beta * error;
+ d_phase = d_phase + d_freq + d_alpha * error;
+ while(d_phase>M_TWOPI)
+ d_phase -= M_TWOPI;
+ while(d_phase<-M_TWOPI)
+ d_phase += M_TWOPI;
+
+ if (d_freq > d_max_freq)
+ d_freq = d_max_freq;
+ else if (d_freq < d_min_freq)
+ d_freq = d_min_freq;
+ }
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_costas_loop_cc.h b/gnuradio-core/src/lib/general/gr_costas_loop_cc.h
new file mode 100644
index 0000000000..4672c0949f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_costas_loop_cc.h
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef INCLUDED_GR_COSTAS_LOOP_CC_H
+#define INCLUDED_GR_COSTAS_LOOP_CC_H
+
+#include <gr_sync_block.h>
+#include <stdexcept>
+
+class gr_costas_loop_cc;
+typedef boost::shared_ptr<gr_costas_loop_cc> gr_costas_loop_cc_sptr;
+
+gr_costas_loop_cc_sptr
+gr_make_costas_loop_cc (float alpha, float beta,
+ float max_freq, float min_freq,
+ int order
+ ) throw (std::invalid_argument);
+
+
+/*!
+ * \brief Carrier tracking PLL for QPSK
+ * input: complex; output: complex
+ *
+ * \p order must be 2 or 4.
+ */
+class gr_costas_loop_cc : public gr_sync_block
+{
+ friend gr_costas_loop_cc_sptr gr_make_costas_loop_cc (float alpha, float beta,
+ float max_freq, float min_freq,
+ int order
+ ) throw (std::invalid_argument);
+
+ float d_alpha, d_beta, d_max_freq, d_min_freq, d_phase, d_freq;
+ int d_order;
+
+ gr_costas_loop_cc (float alpha, float beta,
+ float max_freq, float min_freq,
+ int order
+ ) throw (std::invalid_argument);
+
+ float phase_detector_4(gr_complex sample) const; // for QPSK
+ float phase_detector_2(gr_complex sample) const; // for BPSK
+ float (gr_costas_loop_cc::*d_phase_detector)(gr_complex sample) const;
+
+public:
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_costas_loop_cc.i b/gnuradio-core/src/lib/general/gr_costas_loop_cc.i
new file mode 100644
index 0000000000..85d2ada512
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_costas_loop_cc.i
@@ -0,0 +1,37 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,costas_loop_cc);
+
+gr_costas_loop_cc_sptr
+gr_make_costas_loop_cc (float alpha, float beta,
+ float max_freq, float min_freq,
+ int order
+ ) throw (std::invalid_argument);
+
+
+class gr_costas_loop_cc : public gr_sync_block
+{
+ private:
+ gr_costas_loop_cc (float alpha, float beta,
+ float max_freq, float min_freq, int order);
+};
diff --git a/gnuradio-core/src/lib/general/gr_count_bits.cc b/gnuradio-core/src/lib/general/gr_count_bits.cc
new file mode 100644
index 0000000000..cd51ce8a11
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gr_count_bits.h>
+
+/*
+ * these are slow and obvious. If you need something faster, fix these
+ */
+
+// return number of set bits in the low 8 bits of x
+unsigned int
+gr_count_bits8 (unsigned int x)
+{
+ int count = 0;
+
+ for (int i = 0; i < 8; i++)
+ if (x & (1 << i))
+ count++;
+
+ return count;
+}
+
+// return number of set bits in the low 16 bits of x
+unsigned int
+gr_count_bits16 (unsigned int x)
+{
+ int count = 0;
+
+ for (int i = 0; i < 16; i++)
+ if (x & (1 << i))
+ count++;
+
+ return count;
+
+}
+
+
+#if 0 // slow and obvious
+
+// return number of set bits in the low 32 bits of x
+unsigned int
+gr_count_bits32 (unsigned int x)
+{
+ int count = 0;
+
+ for (int i = 0; i < 32; i++)
+ if (x & (1 << i))
+ count++;
+
+ return count;
+}
+
+#else // fast and not so obvious
+
+// return number of set bits in the low 32 bits of x
+unsigned int
+gr_count_bits32 (unsigned int x)
+{
+ unsigned res = (x & 0x55555555) + ((x >> 1) & 0x55555555);
+ res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
+ res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
+ res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
+ return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
+}
+
+#endif
+
+
+// return number of set bits in the low 64 bits of x
+unsigned int
+gr_count_bits64 (unsigned long long x)
+{
+ return gr_count_bits32((x >> 32) & 0xffffffff) + gr_count_bits32(x & 0xffffffff);
+}
diff --git a/gnuradio-core/src/lib/general/gr_count_bits.h b/gnuradio-core/src/lib/general/gr_count_bits.h
new file mode 100644
index 0000000000..b0e83c832c
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_count_bits.h
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GR_COUNT_BITS_H_
+#define _GR_COUNT_BITS_H_
+
+unsigned int gr_count_bits8(unsigned int x); // return number of set bits in the low 8 bits of x
+unsigned int gr_count_bits16(unsigned int x); // return number of set bits in the low 16 bits of x
+unsigned int gr_count_bits32(unsigned int x); // return number of set bits in the low 32 bits of x
+unsigned int gr_count_bits64(unsigned long long int x);
+
+#endif /* _GR_COUNT_BITS_H_ */
diff --git a/gnuradio-core/src/lib/general/gr_crc32.cc b/gnuradio-core/src/lib/general/gr_crc32.cc
new file mode 100644
index 0000000000..3b0ebd409d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_crc32.cc
@@ -0,0 +1,130 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * See also ISO 3309 [ISO-3309] or ITU-T V.42 [ITU-V42] for a formal specification.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_crc32.h>
+
+
+// Automatically generated CRC function
+// polynomial: 0x104C11DB7
+unsigned int
+gr_update_crc32(unsigned int crc, const unsigned char *data, size_t len)
+{
+ static const unsigned int table[256] = {
+ 0x00000000U,0x04C11DB7U,0x09823B6EU,0x0D4326D9U,
+ 0x130476DCU,0x17C56B6BU,0x1A864DB2U,0x1E475005U,
+ 0x2608EDB8U,0x22C9F00FU,0x2F8AD6D6U,0x2B4BCB61U,
+ 0x350C9B64U,0x31CD86D3U,0x3C8EA00AU,0x384FBDBDU,
+ 0x4C11DB70U,0x48D0C6C7U,0x4593E01EU,0x4152FDA9U,
+ 0x5F15ADACU,0x5BD4B01BU,0x569796C2U,0x52568B75U,
+ 0x6A1936C8U,0x6ED82B7FU,0x639B0DA6U,0x675A1011U,
+ 0x791D4014U,0x7DDC5DA3U,0x709F7B7AU,0x745E66CDU,
+ 0x9823B6E0U,0x9CE2AB57U,0x91A18D8EU,0x95609039U,
+ 0x8B27C03CU,0x8FE6DD8BU,0x82A5FB52U,0x8664E6E5U,
+ 0xBE2B5B58U,0xBAEA46EFU,0xB7A96036U,0xB3687D81U,
+ 0xAD2F2D84U,0xA9EE3033U,0xA4AD16EAU,0xA06C0B5DU,
+ 0xD4326D90U,0xD0F37027U,0xDDB056FEU,0xD9714B49U,
+ 0xC7361B4CU,0xC3F706FBU,0xCEB42022U,0xCA753D95U,
+ 0xF23A8028U,0xF6FB9D9FU,0xFBB8BB46U,0xFF79A6F1U,
+ 0xE13EF6F4U,0xE5FFEB43U,0xE8BCCD9AU,0xEC7DD02DU,
+ 0x34867077U,0x30476DC0U,0x3D044B19U,0x39C556AEU,
+ 0x278206ABU,0x23431B1CU,0x2E003DC5U,0x2AC12072U,
+ 0x128E9DCFU,0x164F8078U,0x1B0CA6A1U,0x1FCDBB16U,
+ 0x018AEB13U,0x054BF6A4U,0x0808D07DU,0x0CC9CDCAU,
+ 0x7897AB07U,0x7C56B6B0U,0x71159069U,0x75D48DDEU,
+ 0x6B93DDDBU,0x6F52C06CU,0x6211E6B5U,0x66D0FB02U,
+ 0x5E9F46BFU,0x5A5E5B08U,0x571D7DD1U,0x53DC6066U,
+ 0x4D9B3063U,0x495A2DD4U,0x44190B0DU,0x40D816BAU,
+ 0xACA5C697U,0xA864DB20U,0xA527FDF9U,0xA1E6E04EU,
+ 0xBFA1B04BU,0xBB60ADFCU,0xB6238B25U,0xB2E29692U,
+ 0x8AAD2B2FU,0x8E6C3698U,0x832F1041U,0x87EE0DF6U,
+ 0x99A95DF3U,0x9D684044U,0x902B669DU,0x94EA7B2AU,
+ 0xE0B41DE7U,0xE4750050U,0xE9362689U,0xEDF73B3EU,
+ 0xF3B06B3BU,0xF771768CU,0xFA325055U,0xFEF34DE2U,
+ 0xC6BCF05FU,0xC27DEDE8U,0xCF3ECB31U,0xCBFFD686U,
+ 0xD5B88683U,0xD1799B34U,0xDC3ABDEDU,0xD8FBA05AU,
+ 0x690CE0EEU,0x6DCDFD59U,0x608EDB80U,0x644FC637U,
+ 0x7A089632U,0x7EC98B85U,0x738AAD5CU,0x774BB0EBU,
+ 0x4F040D56U,0x4BC510E1U,0x46863638U,0x42472B8FU,
+ 0x5C007B8AU,0x58C1663DU,0x558240E4U,0x51435D53U,
+ 0x251D3B9EU,0x21DC2629U,0x2C9F00F0U,0x285E1D47U,
+ 0x36194D42U,0x32D850F5U,0x3F9B762CU,0x3B5A6B9BU,
+ 0x0315D626U,0x07D4CB91U,0x0A97ED48U,0x0E56F0FFU,
+ 0x1011A0FAU,0x14D0BD4DU,0x19939B94U,0x1D528623U,
+ 0xF12F560EU,0xF5EE4BB9U,0xF8AD6D60U,0xFC6C70D7U,
+ 0xE22B20D2U,0xE6EA3D65U,0xEBA91BBCU,0xEF68060BU,
+ 0xD727BBB6U,0xD3E6A601U,0xDEA580D8U,0xDA649D6FU,
+ 0xC423CD6AU,0xC0E2D0DDU,0xCDA1F604U,0xC960EBB3U,
+ 0xBD3E8D7EU,0xB9FF90C9U,0xB4BCB610U,0xB07DABA7U,
+ 0xAE3AFBA2U,0xAAFBE615U,0xA7B8C0CCU,0xA379DD7BU,
+ 0x9B3660C6U,0x9FF77D71U,0x92B45BA8U,0x9675461FU,
+ 0x8832161AU,0x8CF30BADU,0x81B02D74U,0x857130C3U,
+ 0x5D8A9099U,0x594B8D2EU,0x5408ABF7U,0x50C9B640U,
+ 0x4E8EE645U,0x4A4FFBF2U,0x470CDD2BU,0x43CDC09CU,
+ 0x7B827D21U,0x7F436096U,0x7200464FU,0x76C15BF8U,
+ 0x68860BFDU,0x6C47164AU,0x61043093U,0x65C52D24U,
+ 0x119B4BE9U,0x155A565EU,0x18197087U,0x1CD86D30U,
+ 0x029F3D35U,0x065E2082U,0x0B1D065BU,0x0FDC1BECU,
+ 0x3793A651U,0x3352BBE6U,0x3E119D3FU,0x3AD08088U,
+ 0x2497D08DU,0x2056CD3AU,0x2D15EBE3U,0x29D4F654U,
+ 0xC5A92679U,0xC1683BCEU,0xCC2B1D17U,0xC8EA00A0U,
+ 0xD6AD50A5U,0xD26C4D12U,0xDF2F6BCBU,0xDBEE767CU,
+ 0xE3A1CBC1U,0xE760D676U,0xEA23F0AFU,0xEEE2ED18U,
+ 0xF0A5BD1DU,0xF464A0AAU,0xF9278673U,0xFDE69BC4U,
+ 0x89B8FD09U,0x8D79E0BEU,0x803AC667U,0x84FBDBD0U,
+ 0x9ABC8BD5U,0x9E7D9662U,0x933EB0BBU,0x97FFAD0CU,
+ 0xAFB010B1U,0xAB710D06U,0xA6322BDFU,0xA2F33668U,
+ 0xBCB4666DU,0xB8757BDAU,0xB5365D03U,0xB1F740B4U,
+ };
+
+ while (len > 0)
+ {
+ crc = table[*data ^ ((crc >> 24) & 0xff)] ^ (crc << 8);
+ data++;
+ len--;
+ }
+ return crc;
+}
+
+unsigned int
+gr_update_crc32(unsigned int crc, const std::string s)
+{
+ return gr_update_crc32(crc, (const unsigned char *) s.data(), s.size());
+}
+
+unsigned int
+gr_crc32(const unsigned char *buf, size_t len)
+{
+ return gr_update_crc32(0xffffffff, buf, len) ^ 0xffffffff;
+}
+
+unsigned int
+gr_crc32(const std::string s)
+{
+ return gr_crc32((const unsigned char *) s.data(), s.size());
+}
diff --git a/gnuradio-core/src/lib/general/gr_crc32.h b/gnuradio-core/src/lib/general/gr_crc32.h
new file mode 100644
index 0000000000..2d6fdc85dd
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_crc32.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_CRC32_H
+#define INCLUDED_GR_CRC32_H
+
+#include <string>
+#include <gr_types.h>
+
+/*!
+ * \brief update running CRC-32
+ *
+ * Update a running CRC with the bytes buf[0..len-1] The CRC should be
+ * initialized to all 1's, and the transmitted value is the 1's
+ * complement of the final running CRC. The resulting CRC should be
+ * transmitted in big endian order.
+ */
+unsigned int gr_update_crc32(unsigned int crc, const unsigned char *buf, int len);
+unsigned int gr_update_crc32(unsigned int crc, const std::string buf);
+
+unsigned int gr_crc32(const unsigned char *buf, int len);
+unsigned int gr_crc32(const std::string buf);
+
+#endif /* INCLUDED_CRC32_H */
diff --git a/gnuradio-core/src/lib/general/gr_crc32.i b/gnuradio-core/src/lib/general/gr_crc32.i
new file mode 100644
index 0000000000..79e1d08674
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_crc32.i
@@ -0,0 +1,27 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+%rename(update_crc32) gr_update_crc32;
+%rename(crc32) gr_crc32;
+
+unsigned int gr_update_crc32(unsigned int crc, const std::string buf);
+unsigned int gr_crc32(const std::string buf);
diff --git a/gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.cc b/gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.cc
new file mode 100644
index 0000000000..7ad31cbdc4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.cc
@@ -0,0 +1,112 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_ctcss_squelch_ff.h>
+
+static float ctcss_tones[] = {
+ 67.0, 71.9, 74.4, 77.0, 79.7, 82.5, 85.4, 88.5, 91.5, 94.8,
+ 97.4, 100.0, 103.5, 107.2, 110.9, 114.8, 118.8, 123.0, 127.3, 131.8,
+ 136.5, 141.3, 146.2, 151.4, 156.7, 162.2, 167.9, 173.8, 179.9, 186.2,
+ 192.8, 203.5, 210.7, 218.1, 225.7, 233.6, 241.8, 250.3
+};
+
+static int max_tone_index = 37;
+
+gr_ctcss_squelch_ff_sptr
+gr_make_ctcss_squelch_ff(int rate, float freq, float level, int len, int ramp, bool gate)
+{
+ return gr_ctcss_squelch_ff_sptr(new gr_ctcss_squelch_ff(rate, freq, level, len, ramp, gate));
+}
+
+int gr_ctcss_squelch_ff::find_tone(float freq)
+{
+ for (int i = 0; i <= max_tone_index; i++)
+ if (ctcss_tones[i] == freq) // FIXME: make almost equal
+ return i;
+
+ return -1;
+}
+
+gr_ctcss_squelch_ff::gr_ctcss_squelch_ff(int rate, float freq, float level, int len, int ramp, bool gate) :
+ gr_squelch_base_ff("ctcss_squelch_ff", ramp, gate)
+{
+ d_freq = freq;
+ d_level = level;
+
+ // Default is 100 ms detection time
+ if (len == 0)
+ d_len = (int)(rate/10.0);
+ else
+ d_len = len;
+
+ int i = find_tone(freq);
+
+ // Non-standard tones or edge tones get 2% guard band, otherwise
+ // guards are set at adjacent ctcss tone frequencies
+ float f_l, f_r;
+ if (i == -1 || i == 0)
+ f_l = freq*0.98;
+ else
+ f_l = ctcss_tones[i-1];
+
+ if (i == -1 || i == max_tone_index)
+ f_r = freq*1.02;
+ else
+ f_r = ctcss_tones[i+1];
+
+ d_goertzel_l = gri_goertzel(rate, d_len, f_l);
+ d_goertzel_c = gri_goertzel(rate, d_len, freq);
+ d_goertzel_r = gri_goertzel(rate, d_len, f_r);
+
+ d_mute = true;
+}
+
+std::vector<float> gr_ctcss_squelch_ff::squelch_range() const
+{
+ std::vector<float> r(3);
+ r[0] = 0.0;
+ r[1] = 1.0;
+ r[2] = (r[1]-r[0])/100; // step size
+
+ return r;
+}
+
+void gr_ctcss_squelch_ff::update_state(const float &in)
+{
+ d_goertzel_l.input(in);
+ d_goertzel_c.input(in);
+ d_goertzel_r.input(in);
+
+ float d_out_l, d_out_c, d_out_r;
+ if (d_goertzel_c.ready()) {
+ d_out_l = abs(d_goertzel_l.output());
+ d_out_c = abs(d_goertzel_c.output());
+ d_out_r = abs(d_goertzel_r.output());
+
+ //printf("d_out_l=%f d_out_c=%f d_out_r=%f\n", d_out_l, d_out_c, d_out_r);
+ d_mute = (d_out_c < d_level || d_out_c < d_out_l || d_out_c < d_out_r);
+ }
+}
diff --git a/gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.h b/gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.h
new file mode 100644
index 0000000000..337e5cabe6
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.h
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_CTCSS_SQUELCH_FF_H
+#define INCLUDED_GR_CTCSS_SQUELCH_FF_H
+
+#include <gr_squelch_base_ff.h>
+#include <gri_goertzel.h>
+
+class gr_ctcss_squelch_ff;
+typedef boost::shared_ptr<gr_ctcss_squelch_ff> gr_ctcss_squelch_ff_sptr;
+
+gr_ctcss_squelch_ff_sptr
+gr_make_ctcss_squelch_ff(int rate, float freq, float level=0.01, int len=0, int ramp=0, bool gate=false);
+
+/*!
+ * \brief gate or zero output if ctcss tone not present
+ * \ingroup block
+ */
+class gr_ctcss_squelch_ff : public gr_squelch_base_ff
+{
+private:
+ float d_freq;
+ float d_level;
+ int d_len;
+ bool d_mute;
+
+ gri_goertzel d_goertzel_l;
+ gri_goertzel d_goertzel_c;
+ gri_goertzel d_goertzel_r;
+
+ friend gr_ctcss_squelch_ff_sptr gr_make_ctcss_squelch_ff(int rate, float freq, float level, int len, int ramp, bool gate);
+ gr_ctcss_squelch_ff(int rate, float freq, float level, int len, int ramp, bool gate);
+
+ int find_tone(float freq);
+
+protected:
+ virtual void update_state(const float &in);
+ virtual bool mute() const { return d_mute; }
+
+public:
+ std::vector<float> squelch_range() const;
+ float level() const { return d_level; }
+ void set_level(float level) { d_level = level; }
+ int len() const { return d_len; }
+};
+
+#endif /* INCLUDED_GR_CTCSS_SQUELCH_FF_H */
diff --git a/gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.i b/gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.i
new file mode 100644
index 0000000000..6d32c7d0e3
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,ctcss_squelch_ff);
+
+%include gr_squelch_base_ff.i
+
+gr_ctcss_squelch_ff_sptr
+gr_make_ctcss_squelch_ff(int rate, float freq, float level=0.01, int len=0, int ramp=0, bool gate=false);
+
+class gr_ctcss_squelch_ff : public gr_squelch_base_ff
+{
+ gr_ctcss_squelch_ff(int rate, float freq, float level, int len, int ramp, bool gate);
+
+public:
+ std::vector<float> squelch_range() const;
+ float level() const { return d_level; }
+ void set_level(float level) { d_level = level; }
+ int len() const { return d_len; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_dd_mpsk_sync_cc.cc b/gnuradio-core/src/lib/general/gr_dd_mpsk_sync_cc.cc
new file mode 100644
index 0000000000..1f0bc0157f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_dd_mpsk_sync_cc.cc
@@ -0,0 +1,195 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_dd_mpsk_sync_cc.h>
+#include <gr_io_signature.h>
+#include <gr_sincos.h>
+#include <gri_mmse_fir_interpolator_cc.h>
+#include <math.h>
+#include <stdexcept>
+
+#include <gr_complex.h>
+
+#define M_TWOPI (2*M_PI)
+
+gr_dd_mpsk_sync_cc_sptr
+gr_make_dd_mpsk_sync_cc (float alpha, float beta, float max_freq, float min_freq, float ref_phase,
+ float omega, float gain_omega, float mu, float gain_mu)
+{
+ return gr_dd_mpsk_sync_cc_sptr (new gr_dd_mpsk_sync_cc (alpha, beta, max_freq, min_freq,ref_phase,
+ omega,gain_omega,mu,gain_mu));
+}
+
+gr_dd_mpsk_sync_cc::gr_dd_mpsk_sync_cc (float alpha, float beta, float max_freq, float min_freq,
+ float ref_phase,
+ float omega, float gain_omega, float mu, float gain_mu)
+ : gr_block ("dd_mpsk_sync_cc",
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex))),
+ d_alpha(alpha), d_beta(beta),
+ d_max_freq(max_freq), d_min_freq(min_freq),
+ d_ref_phase(ref_phase),d_omega(omega), d_gain_omega(gain_omega),
+ d_mu(mu), d_gain_mu(gain_mu),
+ d_phase(0), d_freq((max_freq+min_freq)/2), d_last_sample(0),
+ d_interp(new gri_mmse_fir_interpolator_cc()),
+ d_dl_idx(0)
+{
+ if (omega <= 0.0)
+ throw std::out_of_range ("clock rate must be > 0");
+ if (gain_mu < 0 || gain_omega < 0)
+ throw std::out_of_range ("Gains must be non-negative");
+
+ assert(d_interp->ntaps() <= DLLEN);
+
+ // zero double length delay line.
+ for (unsigned int i = 0; i < 2 * DLLEN; i++)
+ d_dl[i] = gr_complex(0.0,0.0);
+}
+
+gr_dd_mpsk_sync_cc::~gr_dd_mpsk_sync_cc()
+{
+ delete d_interp;
+}
+
+float
+gr_dd_mpsk_sync_cc::phase_detector(gr_complex sample,float ref_phase)
+{
+ return ((sample.real()>0 ? 1.0 : -1.0) * sample.imag() -
+ (sample.imag()>0 ? 1.0 : -1.0) * sample.real());
+}
+
+void
+gr_dd_mpsk_sync_cc::forecast(int noutput_items, gr_vector_int &ninput_items_required)
+{
+ unsigned ninputs = ninput_items_required.size();
+ for (unsigned i=0; i < ninputs; i++)
+ ninput_items_required[i] =
+ (int) ceil((noutput_items * d_omega) + d_interp->ntaps());
+}
+gr_complex
+gr_dd_mpsk_sync_cc::slicer_45deg (gr_complex sample)
+{
+ float real,imag;
+ if(sample.real() > 0)
+ real=1;
+ else
+ real=-1;
+ if(sample.imag() > 0)
+ imag = 1;
+ else
+ imag = -1;
+ return gr_complex(real,imag);
+}
+
+gr_complex
+gr_dd_mpsk_sync_cc::slicer_0deg (gr_complex sample)
+{
+ gr_complex out;
+ if( fabs(sample.real()) > fabs(sample.imag()) ) {
+ if(sample.real() > 0)
+ return gr_complex(1.0,0.0);
+ else
+ return gr_complex(-1.0,0.0);
+ }
+ else {
+ if(sample.imag() > 0)
+ return gr_complex(0.0, 1.0);
+ else
+ return gr_complex(0.0, -1.0);
+ }
+}
+
+int
+gr_dd_mpsk_sync_cc::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *in = (gr_complex *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ int ii, oo;
+ ii = 0; oo = 0;
+
+ float error;
+ float t_imag, t_real;
+ gr_complex nco_out;
+ float mm_val;
+
+ while (oo < noutput_items) {
+ //
+ // generate an output sample by interpolating between the carrier
+ // tracked samples in the delay line. d_mu, the fractional
+ // interpolation amount (in [0.0, 1.0]) is controlled by the
+ // symbol timing loop below.
+ //
+ out[oo] = d_interp->interpolate (&d_dl[d_dl_idx], d_mu);
+
+ error = phase_detector(out[oo], d_ref_phase);
+
+ d_freq = d_freq + d_beta * error;
+ d_phase = d_phase + d_alpha * error;
+ while(d_phase>M_TWOPI)
+ d_phase -= M_TWOPI;
+ while(d_phase<-M_TWOPI)
+ d_phase += M_TWOPI;
+
+ if (d_freq > d_max_freq)
+ d_freq = d_max_freq;
+ else if (d_freq < d_min_freq)
+ d_freq = d_min_freq;
+
+ mm_val = real(d_last_sample * slicer_0deg(out[oo]) - out[oo] * slicer_0deg(d_last_sample));
+ d_last_sample = out[oo];
+
+ d_omega = d_omega + d_gain_omega * mm_val;
+ d_mu = d_mu + d_omega + d_gain_mu * mm_val;
+
+ while(d_mu >= 1.0) {
+ //
+ // Generate more carrier tracked samples for the delay line
+ //
+ d_mu -= 1.0;
+ gr_sincosf(d_phase, &t_imag, &t_real);
+ nco_out = gr_complex(t_real, -t_imag);
+ gr_complex new_sample = in[ii] * nco_out;
+
+ d_dl[d_dl_idx] = new_sample; // overwrite oldest sample
+ d_dl[(d_dl_idx + DLLEN)] = new_sample; // and second copy
+ d_dl_idx = (d_dl_idx+1) % DLLEN; // point to the new oldest sample
+ d_phase = d_phase + d_freq;
+ ii++;
+ }
+ oo++;
+ printf("%f\t%f\t%f\t%f\t%f\n",d_mu,d_omega,mm_val,d_freq,d_phase);
+ //printf("%f\t%f\t%f\t%f\t%f\t%f\t%f\n",mple).real(),slicer_0deg(d_last_sample).imag(),mm_val,d_omega,d_mu);
+ }
+
+ assert(ii <= ninput_items[0]);
+
+ consume_each (ii);
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_dd_mpsk_sync_cc.h b/gnuradio-core/src/lib/general/gr_dd_mpsk_sync_cc.h
new file mode 100644
index 0000000000..fdc2561425
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_dd_mpsk_sync_cc.h
@@ -0,0 +1,92 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_DD_MPSK_SYNC_CC_H
+#define INCLUDED_GR_DD_MPSK_SYNC_CC_H
+
+#include <gr_sync_block.h>
+
+class gri_mmse_fir_interpolator_cc;
+
+class gr_dd_mpsk_sync_cc;
+typedef boost::shared_ptr<gr_dd_mpsk_sync_cc> gr_dd_mpsk_sync_cc_sptr;
+
+gr_dd_mpsk_sync_cc_sptr
+gr_make_dd_mpsk_sync_cc (float alpha, float beta,
+ float max_freq, float min_freq, float ref_phase,
+ float omega, float gain_omega, float mu, float gain_mu);
+
+/*!
+ * \brief Decision directed M-PSK synchronous demod
+ * This block performs joint carrier tracking and symbol timing recovery.
+ *
+ * input: complex baseband; output: properly timed complex samples ready for slicing.
+ *
+ * N.B, at this point, it handles only QPSK.
+ */
+
+class gr_dd_mpsk_sync_cc : public gr_block
+{
+ friend gr_dd_mpsk_sync_cc_sptr gr_make_dd_mpsk_sync_cc (float alpha, float beta,
+ float max_freq, float min_freq, float ref_phase,
+ float omega, float gain_omega, float mu, float gain_mu);
+public:
+ ~gr_dd_mpsk_sync_cc ();
+ void forecast(int noutput_items, gr_vector_int &ninput_items_required);
+ float mu() const { return d_mu;}
+ float omega() const { return d_omega;}
+ float gain_mu() const { return d_gain_mu;}
+ float gain_omega() const { return d_gain_omega;}
+
+ void set_gain_mu (float gain_mu) { d_gain_mu = gain_mu; }
+ void set_gain_omega (float gain_omega) { d_gain_omega = gain_omega; }
+ void set_mu (float mu) { d_mu = mu; }
+ void set_omega (float omega) { d_omega = omega; }
+
+protected:
+ gr_dd_mpsk_sync_cc (float alpha, float beta, float max_freq, float min_freq, float ref_phase,
+ float omega, float gain_omega, float mu, float gain_mu);
+
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+private:
+ static const unsigned int DLLEN = 8; // delay line length.
+
+ float d_alpha,d_beta,d_max_freq,d_min_freq,d_ref_phase;
+ float d_omega, d_gain_omega, d_mu, d_gain_mu;
+ float d_phase, d_freq;
+ gr_complex slicer_45deg (gr_complex sample);
+ gr_complex slicer_0deg (gr_complex sample);
+ gr_complex d_last_sample;
+ gri_mmse_fir_interpolator_cc *d_interp;
+
+ gr_complex d_dl[2 * DLLEN]; // Holds post carrier tracking samples.
+ // double length delay line to avoid wraps.
+ unsigned int d_dl_idx; // indexes oldest sample in delay line.
+
+ float phase_detector(gr_complex sample,float ref_phase);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_dd_mpsk_sync_cc.i b/gnuradio-core/src/lib/general/gr_dd_mpsk_sync_cc.i
new file mode 100644
index 0000000000..3bab9e2f30
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_dd_mpsk_sync_cc.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,dd_mpsk_sync_cc)
+
+ gr_dd_mpsk_sync_cc_sptr gr_make_dd_mpsk_sync_cc (float alpha, float beta,
+ float max_freq, float min_freq, float ref_phase,
+ float omega, float gain_omega, float mu, float gain_mu);
+
+class gr_dd_mpsk_sync_cc : public gr_block
+{
+ private:
+ gr_dd_mpsk_sync_cc (float alpha, float beta, float max_freq, float min_freq, float ref_phase,
+ float omega, float gain_omega, float mu, float gain_mu);
+};
diff --git a/gnuradio-core/src/lib/general/gr_deinterleave.cc b/gnuradio-core/src/lib/general/gr_deinterleave.cc
new file mode 100644
index 0000000000..375a40d21f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_deinterleave.cc
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_deinterleave.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+
+gr_deinterleave_sptr
+gr_make_deinterleave (size_t itemsize)
+{
+ return gr_deinterleave_sptr (new gr_deinterleave (itemsize));
+}
+
+gr_deinterleave::gr_deinterleave (size_t itemsize)
+ : gr_sync_decimator ("deinterleave",
+ gr_make_io_signature (1, 1, itemsize),
+ gr_make_io_signature (1, gr_io_signature::IO_INFINITE, itemsize),
+ 1),
+ d_itemsize (itemsize)
+{
+}
+
+gr_deinterleave::~gr_deinterleave ()
+{
+ // NOP
+}
+
+bool
+gr_deinterleave::check_topology (int ninputs, int noutputs)
+{
+ set_decimation (noutputs);
+ return true;
+}
+
+int
+gr_deinterleave::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ size_t nchan = output_items.size ();
+ size_t itemsize = d_itemsize;
+ const char *in = (const char *) input_items[0];
+ char **out = (char **) &output_items[0];
+
+ for (int i = 0; i < noutput_items; i++){
+ for (unsigned int n = 0; n < nchan; n++){
+ memcpy (out[n], in, itemsize);
+ out[n] += itemsize;
+ in += itemsize;
+ }
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_deinterleave.h b/gnuradio-core/src/lib/general/gr_deinterleave.h
new file mode 100644
index 0000000000..0eb9874eda
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_deinterleave.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_DEINTERLEAVE_H
+#define INCLUDED_GR_DEINTERLEAVE_H
+
+#include <gr_sync_decimator.h>
+
+class gr_deinterleave;
+typedef boost::shared_ptr<gr_deinterleave> gr_deinterleave_sptr;
+
+gr_deinterleave_sptr gr_make_deinterleave (size_t itemsize);
+
+/*!
+ * \brief deinterleave a single input into N outputs
+ * \ingroup block
+ */
+class gr_deinterleave : public gr_sync_decimator
+{
+ friend gr_deinterleave_sptr gr_make_deinterleave (size_t itemsize);
+
+ size_t d_itemsize;
+
+ gr_deinterleave (size_t itemsize);
+
+public:
+ ~gr_deinterleave ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ bool check_topology (int ninputs, int noutputs);
+
+};
+
+#endif /* INCLUDED_GR_DEINTERLEAVE_H */
diff --git a/gnuradio-core/src/lib/general/gr_deinterleave.i b/gnuradio-core/src/lib/general/gr_deinterleave.i
new file mode 100644
index 0000000000..f1eac5cab2
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,deinterleave)
+
+gr_deinterleave_sptr gr_make_deinterleave (size_t itemsize);
+
+class gr_deinterleave : public gr_sync_decimator
+{
+ gr_deinterleave (size_t itemsize);
+};
diff --git a/gnuradio-core/src/lib/general/gr_diff_decoder_bb.cc b/gnuradio-core/src/lib/general/gr_diff_decoder_bb.cc
new file mode 100644
index 0000000000..5ab88a9c01
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_diff_decoder_bb.cc
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_diff_decoder_bb.h>
+#include <gr_io_signature.h>
+
+gr_diff_decoder_bb_sptr
+gr_make_diff_decoder_bb (unsigned int modulus)
+{
+ return gr_diff_decoder_bb_sptr (new gr_diff_decoder_bb(modulus));
+}
+
+gr_diff_decoder_bb::gr_diff_decoder_bb (unsigned int modulus)
+ : gr_sync_block ("diff_decoder_bb",
+ gr_make_io_signature (1, 1, sizeof (unsigned char)),
+ gr_make_io_signature (1, 1, sizeof (unsigned char))),
+ d_modulus(modulus)
+{
+ set_history(2); // need to look at two inputs
+}
+
+int
+gr_diff_decoder_bb::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+ in += 1; // ensure that in[-1] is valid
+
+ unsigned modulus = d_modulus;
+
+ for (int i = 0; i < noutput_items; i++){
+ out[i] = (in[i] - in[i-1]) % modulus;
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_diff_decoder_bb.h b/gnuradio-core/src/lib/general/gr_diff_decoder_bb.h
new file mode 100644
index 0000000000..c88e0e25b1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_diff_decoder_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_DIFF_DECODER_BB_H
+#define INCLUDED_GR_DIFF_DECODER_BB_H
+
+#include <gr_sync_block.h>
+
+class gr_diff_decoder_bb;
+typedef boost::shared_ptr<gr_diff_decoder_bb> gr_diff_decoder_bb_sptr;
+
+gr_diff_decoder_bb_sptr gr_make_diff_decoder_bb (unsigned int modulus);
+
+/*!
+ * \brief y[0] = (x[0] - x[-1]) % M
+ * \ingroup block
+ *
+ * Differential decoder
+ */
+class gr_diff_decoder_bb : public gr_sync_block
+{
+ friend gr_diff_decoder_bb_sptr gr_make_diff_decoder_bb (unsigned int modulus);
+ gr_diff_decoder_bb(unsigned int modulus);
+
+ unsigned int d_modulus;
+
+ public:
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_diff_decoder_bb.i b/gnuradio-core/src/lib/general/gr_diff_decoder_bb.i
new file mode 100644
index 0000000000..b4ad5f6ad8
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,diff_decoder_bb)
+
+gr_diff_decoder_bb_sptr gr_make_diff_decoder_bb (unsigned int modulus);
+
+class gr_diff_decoder_bb : public gr_sync_block
+{
+ private:
+ gr_diff_decoder_bb (unsigned int modulus);
+};
diff --git a/gnuradio-core/src/lib/general/gr_diff_encoder_bb.cc b/gnuradio-core/src/lib/general/gr_diff_encoder_bb.cc
new file mode 100644
index 0000000000..bd4135c4ca
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_diff_encoder_bb.cc
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_diff_encoder_bb.h>
+#include <gr_io_signature.h>
+
+gr_diff_encoder_bb_sptr
+gr_make_diff_encoder_bb (unsigned int modulus)
+{
+ return gr_diff_encoder_bb_sptr (new gr_diff_encoder_bb(modulus));
+}
+
+gr_diff_encoder_bb::gr_diff_encoder_bb (unsigned int modulus)
+ : gr_sync_block ("diff_encoder_bb",
+ gr_make_io_signature (1, 1, sizeof (unsigned char)),
+ gr_make_io_signature (1, 1, sizeof (unsigned char))),
+ d_last_out(0), d_modulus(modulus)
+{
+}
+
+int
+gr_diff_encoder_bb::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+
+ unsigned last_out = d_last_out;
+ unsigned modulus = d_modulus;
+
+ for (int i = 0; i < noutput_items; i++){
+ out[i] = (in[i] + last_out) % modulus;
+ last_out = out[i];
+ }
+
+ d_last_out = last_out;
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_diff_encoder_bb.h b/gnuradio-core/src/lib/general/gr_diff_encoder_bb.h
new file mode 100644
index 0000000000..c839d399fa
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_diff_encoder_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_DIFF_ENCODER_BB_H
+#define INCLUDED_GR_DIFF_ENCODER_BB_H
+
+#include <gr_sync_block.h>
+
+class gr_diff_encoder_bb;
+typedef boost::shared_ptr<gr_diff_encoder_bb> gr_diff_encoder_bb_sptr;
+
+gr_diff_encoder_bb_sptr gr_make_diff_encoder_bb (unsigned int modulus);
+
+/*!
+ * \brief y[0] = (x[0] + y[-1]) % M
+ * \ingroup block
+ *
+ * Differential encoder
+ */
+class gr_diff_encoder_bb : public gr_sync_block
+{
+ friend gr_diff_encoder_bb_sptr gr_make_diff_encoder_bb (unsigned int modulus);
+ gr_diff_encoder_bb(unsigned int modulus);
+
+ unsigned int d_last_out;
+ unsigned int d_modulus;
+
+ public:
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_diff_encoder_bb.i b/gnuradio-core/src/lib/general/gr_diff_encoder_bb.i
new file mode 100644
index 0000000000..890779c469
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,diff_encoder_bb)
+
+gr_diff_encoder_bb_sptr gr_make_diff_encoder_bb (unsigned int modulus);
+
+class gr_diff_encoder_bb : public gr_sync_block
+{
+ private:
+ gr_diff_encoder_bb (unsigned int modulus);
+};
diff --git a/gnuradio-core/src/lib/general/gr_diff_phasor_cc.cc b/gnuradio-core/src/lib/general/gr_diff_phasor_cc.cc
new file mode 100644
index 0000000000..c5eae5f336
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_diff_phasor_cc.cc
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_diff_phasor_cc.h>
+#include <gr_io_signature.h>
+
+gr_diff_phasor_cc_sptr
+gr_make_diff_phasor_cc ()
+{
+ return gr_diff_phasor_cc_sptr (new gr_diff_phasor_cc());
+}
+
+gr_diff_phasor_cc::gr_diff_phasor_cc ()
+ : gr_sync_block ("diff_phasor_cc",
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex)))
+{
+ set_history(2);
+}
+
+
+gr_diff_phasor_cc::~gr_diff_phasor_cc(){}
+
+int
+gr_diff_phasor_cc::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ gr_complex const *in = (const gr_complex *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+ in += 1; // ensure that i - 1 is valid.
+
+ for(int i = 0; i < noutput_items; i++){
+ out[i] = in[i] * conj(in[i-1]);
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_diff_phasor_cc.h b/gnuradio-core/src/lib/general/gr_diff_phasor_cc.h
new file mode 100644
index 0000000000..64a3f291b5
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_diff_phasor_cc.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_DIFF_PHASOR_CC_H
+#define INCLUDED_GR_DIFF_PHASOR_CC_H
+
+#include <gr_sync_block.h>
+
+class gr_diff_phasor_cc;
+typedef boost::shared_ptr<gr_diff_phasor_cc> gr_diff_phasor_cc_sptr;
+
+gr_diff_phasor_cc_sptr gr_make_diff_phasor_cc ();
+
+
+class gr_diff_phasor_cc : public gr_sync_block
+{
+ friend gr_diff_phasor_cc_sptr gr_make_diff_phasor_cc ();
+
+ gr_diff_phasor_cc (); //constructor
+
+ public:
+ ~gr_diff_phasor_cc(); //destructor
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_diff_phasor_cc.i b/gnuradio-core/src/lib/general/gr_diff_phasor_cc.i
new file mode 100644
index 0000000000..773d276ba9
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,diff_phasor_cc)
+
+gr_diff_phasor_cc_sptr gr_make_diff_phasor_cc ();
+
+class gr_diff_phasor_cc : public gr_sync_block
+{
+ private:
+ gr_diff_phasor_cc ();
+
+ public:
+ ~gr_diff_phasor_cc();
+};
diff --git a/gnuradio-core/src/lib/general/gr_divide_XX.cc.t b/gnuradio-core/src/lib/general/gr_divide_XX.cc.t
new file mode 100644
index 0000000000..e85f7b0a50
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_divide_XX.cc.t
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ ()
+{
+ return @SPTR_NAME@ (new @NAME@ ());
+}
+
+@NAME@::@NAME@ ()
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (1, -1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@)))
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0];
+
+ int ninputs = input_items.size ();
+
+ if (ninputs == 1){ // compute reciprocal
+ for (int i = 0; i < noutput_items; i++)
+ *optr++ = (@O_TYPE@) ((@O_TYPE@) 1 /
+ ((@I_TYPE@ *) input_items[0])[i]);
+ }
+
+ else {
+ for (int i = 0; i < noutput_items; i++){
+ @I_TYPE@ acc = ((@I_TYPE@ *) input_items[0])[i];
+ for (int j = 1; j < ninputs; j++)
+ acc /= ((@I_TYPE@ *) input_items[j])[i];
+
+ *optr++ = (@O_TYPE@) acc;
+ }
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_divide_XX.h.t b/gnuradio-core/src/lib/general/gr_divide_XX.h.t
new file mode 100644
index 0000000000..193d6f82a2
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_divide_XX.h.t
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+/*!
+ * \brief output = input_0 / input_1 / input_x ...)
+ * \ingroup block
+ *
+ * Divide across all input streams.
+ */
+class @NAME@ : public gr_sync_block
+{
+ friend @SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+ @NAME@ ();
+
+ public:
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_divide_XX.i.t b/gnuradio-core/src/lib/general/gr_divide_XX.i.t
new file mode 100644
index 0000000000..8479aad683
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_divide_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+ @NAME@ ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_endianness.h b/gnuradio-core/src/lib/general/gr_endianness.h
new file mode 100644
index 0000000000..e33af166d1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_ENDIANNESS_H
+#define INCLUDED_GR_ENDIANNESS_H
+
+typedef enum {GR_MSB_FIRST, GR_LSB_FIRST} gr_endianness_t;
+
+#endif /* INCLUDED_GR_ENDIANNESS_H */
diff --git a/gnuradio-core/src/lib/general/gr_endianness.i b/gnuradio-core/src/lib/general/gr_endianness.i
new file mode 100644
index 0000000000..d05b06a099
--- /dev/null
+++ b/gnuradio-core/src/lib/general/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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+%include <gr_endianness.h>
diff --git a/gnuradio-core/src/lib/general/gr_expj.h b/gnuradio-core/src/lib/general/gr_expj.h
new file mode 100644
index 0000000000..502bfe9ee4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_expj.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_EXPJ_H
+#define INCLUDED_GR_EXPJ_H
+
+#include <gr_sincos.h>
+#include <gr_types.h>
+
+static inline gr_complex
+gr_expj(float phase)
+{
+ float t_imag, t_real;
+ gr_sincosf(phase, &t_imag, &t_real);
+ return gr_complex(t_real, t_imag);
+}
+
+
+#endif /* INCLUDED_GR_EXPJ_H */
diff --git a/gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.cc b/gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.cc
new file mode 100644
index 0000000000..0ef4c46dbe
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.cc
@@ -0,0 +1,112 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_fake_channel_coder_pp.h>
+#include <gr_io_signature.h>
+#include <string.h>
+#include <stdexcept>
+
+static const int PAD_VAL = 0xAA;
+
+gr_fake_channel_encoder_pp_sptr
+gr_make_fake_channel_encoder_pp(int input_vlen, int output_vlen)
+{
+ return gr_fake_channel_encoder_pp_sptr(new gr_fake_channel_encoder_pp(input_vlen,
+ output_vlen));
+}
+
+gr_fake_channel_encoder_pp::gr_fake_channel_encoder_pp(int input_vlen, int output_vlen)
+ : gr_sync_block("fake_channel_encoder_pp",
+ gr_make_io_signature(1, 1, input_vlen * sizeof(unsigned char)),
+ gr_make_io_signature(1, 1, output_vlen * sizeof(unsigned char))),
+ d_input_vlen(input_vlen), d_output_vlen(output_vlen)
+{
+ if (input_vlen <= 0 || output_vlen <= 0 || input_vlen > output_vlen)
+ throw std::invalid_argument("gr_fake_channel_encoder_pp");
+}
+
+gr_fake_channel_encoder_pp::~gr_fake_channel_encoder_pp()
+{
+}
+
+int
+gr_fake_channel_encoder_pp::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+ int npad = d_output_vlen - d_input_vlen;
+
+ for (int i = 0; i < noutput_items; i++){
+ memcpy(out, in, d_input_vlen);
+ memset(out + d_input_vlen, PAD_VAL, npad);
+ in += d_input_vlen;
+ out += d_output_vlen;
+ }
+
+ return noutput_items;
+}
+
+// ------------------------------------------------------------------------
+
+gr_fake_channel_decoder_pp_sptr
+gr_make_fake_channel_decoder_pp(int input_vlen, int output_vlen)
+{
+ return gr_fake_channel_decoder_pp_sptr(new gr_fake_channel_decoder_pp(input_vlen,
+ output_vlen));
+}
+
+gr_fake_channel_decoder_pp::gr_fake_channel_decoder_pp(int input_vlen, int output_vlen)
+ : gr_sync_block("fake_channel_decoder_pp",
+ gr_make_io_signature(1, 1, input_vlen * sizeof(unsigned char)),
+ gr_make_io_signature(1, 1, output_vlen * sizeof(unsigned char))),
+ d_input_vlen(input_vlen), d_output_vlen(output_vlen)
+{
+ if (input_vlen <= 0 || output_vlen <= 0 || output_vlen > input_vlen)
+ throw std::invalid_argument("gr_fake_channel_decoder_pp");
+}
+
+gr_fake_channel_decoder_pp::~gr_fake_channel_decoder_pp()
+{
+}
+
+int
+gr_fake_channel_decoder_pp::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+
+ for (int i = 0; i < noutput_items; i++){
+ memcpy(out, in, d_output_vlen);
+ in += d_input_vlen;
+ out += d_output_vlen;
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.h b/gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.h
new file mode 100644
index 0000000000..03b651e83f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_FAKE_CHANNEL_CODER_PP_H
+#define INCLUDED_GR_FAKE_CHANNEL_CODER_PP_H
+
+#include <gr_sync_block.h>
+
+class gr_fake_channel_encoder_pp;
+typedef boost::shared_ptr<gr_fake_channel_encoder_pp> gr_fake_channel_encoder_pp_sptr;
+
+gr_fake_channel_encoder_pp_sptr
+gr_make_fake_channel_encoder_pp(int input_vlen, int output_vlen);
+
+/*!
+ * \brief pad packet with alternating 1,0 pattern.
+ * \ingroup block
+ *
+ * input: stream of byte vectors; output: stream of byte vectors
+ */
+class gr_fake_channel_encoder_pp : public gr_sync_block
+{
+ int d_input_vlen;
+ int d_output_vlen;
+
+ gr_fake_channel_encoder_pp(int input_vlen, int output_vlen);
+
+ friend gr_fake_channel_encoder_pp_sptr
+ gr_make_fake_channel_encoder_pp(int input_vlen, int output_vlen);
+
+public:
+ ~gr_fake_channel_encoder_pp();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+// ------------------------------------------------------------------------
+
+class gr_fake_channel_decoder_pp;
+typedef boost::shared_ptr<gr_fake_channel_decoder_pp> gr_fake_channel_decoder_pp_sptr;
+
+gr_fake_channel_decoder_pp_sptr
+gr_make_fake_channel_decoder_pp(int input_vlen, int output_vlen);
+
+/*!
+ * \brief remove fake padding from packet
+ * \ingroup block
+ *
+ * input: stream of byte vectors; output: stream of byte vectors
+ */
+class gr_fake_channel_decoder_pp : public gr_sync_block
+{
+ int d_input_vlen;
+ int d_output_vlen;
+
+ gr_fake_channel_decoder_pp(int input_vlen, int output_vlen);
+
+ friend gr_fake_channel_decoder_pp_sptr
+ gr_make_fake_channel_decoder_pp(int input_vlen, int output_vlen);
+
+public:
+ ~gr_fake_channel_decoder_pp();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_FAKE_CHANNEL_CODER_PP_H */
diff --git a/gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.i b/gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.i
new file mode 100644
index 0000000000..3bf394e272
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,fake_channel_encoder_pp)
+
+gr_fake_channel_encoder_pp_sptr
+gr_make_fake_channel_encoder_pp(int input_vlen,
+ int output_vlen
+ ) throw(std::invalid_argument);
+
+class gr_fake_channel_encoder_pp : public gr_sync_block
+{
+ gr_fake_channel_encoder_pp(int input_vlen, int output_vlen);
+
+public:
+ ~gr_fake_channel_encoder_pp();
+};
+
+// ------------------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(gr,fake_channel_decoder_pp)
+
+gr_fake_channel_decoder_pp_sptr
+gr_make_fake_channel_decoder_pp(int input_vlen,
+ int output_vlen
+ ) throw(std::invalid_argument);
+
+class gr_fake_channel_decoder_pp : public gr_sync_block
+{
+ gr_fake_channel_decoder_pp(int input_vlen, int output_vlen);
+
+public:
+ ~gr_fake_channel_decoder_pp();
+};
diff --git a/gnuradio-core/src/lib/general/gr_fast_atan2f.cc b/gnuradio-core/src/lib/general/gr_fast_atan2f.cc
new file mode 100644
index 0000000000..ebbece57f5
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fast_atan2f.cc
@@ -0,0 +1,198 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gr_math.h> // declaration is in here
+#include <cmath>
+
+#define REAL float
+
+/***************************************************************************/
+/* Constant definitions */
+/***************************************************************************/
+
+#define TAN_MAP_RES 0.003921569 /* (smallest non-zero value in table) */
+#define RAD_PER_DEG 0.017453293
+#define TAN_MAP_SIZE 256
+
+/* arctangents from 0 to pi/4 radians */
+static REAL
+fast_atan_table[257] = {
+ 0.000000e+00, 3.921549e-03, 7.842976e-03, 1.176416e-02,
+ 1.568499e-02, 1.960533e-02, 2.352507e-02, 2.744409e-02,
+ 3.136226e-02, 3.527947e-02, 3.919560e-02, 4.311053e-02,
+ 4.702413e-02, 5.093629e-02, 5.484690e-02, 5.875582e-02,
+ 6.266295e-02, 6.656816e-02, 7.047134e-02, 7.437238e-02,
+ 7.827114e-02, 8.216752e-02, 8.606141e-02, 8.995267e-02,
+ 9.384121e-02, 9.772691e-02, 1.016096e-01, 1.054893e-01,
+ 1.093658e-01, 1.132390e-01, 1.171087e-01, 1.209750e-01,
+ 1.248376e-01, 1.286965e-01, 1.325515e-01, 1.364026e-01,
+ 1.402496e-01, 1.440924e-01, 1.479310e-01, 1.517652e-01,
+ 1.555948e-01, 1.594199e-01, 1.632403e-01, 1.670559e-01,
+ 1.708665e-01, 1.746722e-01, 1.784728e-01, 1.822681e-01,
+ 1.860582e-01, 1.898428e-01, 1.936220e-01, 1.973956e-01,
+ 2.011634e-01, 2.049255e-01, 2.086818e-01, 2.124320e-01,
+ 2.161762e-01, 2.199143e-01, 2.236461e-01, 2.273716e-01,
+ 2.310907e-01, 2.348033e-01, 2.385093e-01, 2.422086e-01,
+ 2.459012e-01, 2.495869e-01, 2.532658e-01, 2.569376e-01,
+ 2.606024e-01, 2.642600e-01, 2.679104e-01, 2.715535e-01,
+ 2.751892e-01, 2.788175e-01, 2.824383e-01, 2.860514e-01,
+ 2.896569e-01, 2.932547e-01, 2.968447e-01, 3.004268e-01,
+ 3.040009e-01, 3.075671e-01, 3.111252e-01, 3.146752e-01,
+ 3.182170e-01, 3.217506e-01, 3.252758e-01, 3.287927e-01,
+ 3.323012e-01, 3.358012e-01, 3.392926e-01, 3.427755e-01,
+ 3.462497e-01, 3.497153e-01, 3.531721e-01, 3.566201e-01,
+ 3.600593e-01, 3.634896e-01, 3.669110e-01, 3.703234e-01,
+ 3.737268e-01, 3.771211e-01, 3.805064e-01, 3.838825e-01,
+ 3.872494e-01, 3.906070e-01, 3.939555e-01, 3.972946e-01,
+ 4.006244e-01, 4.039448e-01, 4.072558e-01, 4.105574e-01,
+ 4.138496e-01, 4.171322e-01, 4.204054e-01, 4.236689e-01,
+ 4.269229e-01, 4.301673e-01, 4.334021e-01, 4.366272e-01,
+ 4.398426e-01, 4.430483e-01, 4.462443e-01, 4.494306e-01,
+ 4.526070e-01, 4.557738e-01, 4.589307e-01, 4.620778e-01,
+ 4.652150e-01, 4.683424e-01, 4.714600e-01, 4.745676e-01,
+ 4.776654e-01, 4.807532e-01, 4.838312e-01, 4.868992e-01,
+ 4.899573e-01, 4.930055e-01, 4.960437e-01, 4.990719e-01,
+ 5.020902e-01, 5.050985e-01, 5.080968e-01, 5.110852e-01,
+ 5.140636e-01, 5.170320e-01, 5.199904e-01, 5.229388e-01,
+ 5.258772e-01, 5.288056e-01, 5.317241e-01, 5.346325e-01,
+ 5.375310e-01, 5.404195e-01, 5.432980e-01, 5.461666e-01,
+ 5.490251e-01, 5.518738e-01, 5.547124e-01, 5.575411e-01,
+ 5.603599e-01, 5.631687e-01, 5.659676e-01, 5.687566e-01,
+ 5.715357e-01, 5.743048e-01, 5.770641e-01, 5.798135e-01,
+ 5.825531e-01, 5.852828e-01, 5.880026e-01, 5.907126e-01,
+ 5.934128e-01, 5.961032e-01, 5.987839e-01, 6.014547e-01,
+ 6.041158e-01, 6.067672e-01, 6.094088e-01, 6.120407e-01,
+ 6.146630e-01, 6.172755e-01, 6.198784e-01, 6.224717e-01,
+ 6.250554e-01, 6.276294e-01, 6.301939e-01, 6.327488e-01,
+ 6.352942e-01, 6.378301e-01, 6.403565e-01, 6.428734e-01,
+ 6.453808e-01, 6.478788e-01, 6.503674e-01, 6.528466e-01,
+ 6.553165e-01, 6.577770e-01, 6.602282e-01, 6.626701e-01,
+ 6.651027e-01, 6.675261e-01, 6.699402e-01, 6.723452e-01,
+ 6.747409e-01, 6.771276e-01, 6.795051e-01, 6.818735e-01,
+ 6.842328e-01, 6.865831e-01, 6.889244e-01, 6.912567e-01,
+ 6.935800e-01, 6.958943e-01, 6.981998e-01, 7.004964e-01,
+ 7.027841e-01, 7.050630e-01, 7.073330e-01, 7.095943e-01,
+ 7.118469e-01, 7.140907e-01, 7.163258e-01, 7.185523e-01,
+ 7.207701e-01, 7.229794e-01, 7.251800e-01, 7.273721e-01,
+ 7.295557e-01, 7.317307e-01, 7.338974e-01, 7.360555e-01,
+ 7.382053e-01, 7.403467e-01, 7.424797e-01, 7.446045e-01,
+ 7.467209e-01, 7.488291e-01, 7.509291e-01, 7.530208e-01,
+ 7.551044e-01, 7.571798e-01, 7.592472e-01, 7.613064e-01,
+ 7.633576e-01, 7.654008e-01, 7.674360e-01, 7.694633e-01,
+ 7.714826e-01, 7.734940e-01, 7.754975e-01, 7.774932e-01,
+ 7.794811e-01, 7.814612e-01, 7.834335e-01, 7.853983e-01,
+ 7.853983e-01
+ };
+
+
+/*****************************************************************************
+Function: Arc tangent
+
+Syntax: angle = fast_atan2(y, x);
+REAL y y component of input vector
+REAL x x component of input vector
+REAL angle angle of vector (x, y) in radians
+
+Description: This function calculates the angle of the vector (x,y) based
+on a table lookup and linear interpolation. The table uses
+a 256 point table covering -45 to +45 degrees and uses
+symetry to determine the final angle value in the range of
+-180 to 180 degrees. Note that this function uses the small
+angle approximation for values close to zero. This routine
+calculates the arc tangent with an average error of
++/- 0.045 degrees.
+*****************************************************************************/
+
+REAL
+gr_fast_atan2f(REAL y, REAL x)
+{
+ REAL x_abs, y_abs, z;
+ REAL alpha, angle, base_angle;
+ int index;
+
+ /* don't divide by zero! */ // FIXME could get hosed with -0.0
+ if ((y == 0.0) && (x == 0.0))
+ return 0.0;
+
+ /* normalize to +/- 45 degree range */
+ y_abs = fabs(y);
+ x_abs = fabs(x);
+ //z = (y_abs < x_abs ? y_abs / x_abs : x_abs / y_abs);
+ if (y_abs < x_abs)
+ z = y_abs / x_abs;
+ else
+ z = x_abs / y_abs;
+
+ /* when ratio approaches the table resolution, the angle is */
+ /* best approximated with the argument itself... */
+ if (z < TAN_MAP_RES)
+ base_angle = z;
+ else {
+ /* find index and interpolation value */
+ alpha = z * (REAL) TAN_MAP_SIZE - .5;
+ index = (int) alpha;
+ alpha -= (REAL) index;
+ /* determine base angle based on quadrant and */
+ /* add or subtract table value from base angle based on quadrant */
+ base_angle = fast_atan_table[index];
+ base_angle +=
+ (fast_atan_table[index + 1] - fast_atan_table[index]) * alpha;
+ }
+
+ if (x_abs > y_abs) { /* -45 -> 45 or 135 -> 225 */
+ if (x >= 0.0) { /* -45 -> 45 */
+ if (y >= 0.0)
+ angle = base_angle; /* 0 -> 45, angle OK */
+ else
+ angle = -base_angle; /* -45 -> 0, angle = -angle */
+ } else { /* 135 -> 180 or 180 -> -135 */
+ angle = 3.14159265358979323846;
+ if (y >= 0.0)
+ angle -= base_angle; /* 135 -> 180, angle = 180 - angle */
+ else
+ angle = base_angle - angle; /* 180 -> -135, angle = angle - 180 */
+ }
+ } else { /* 45 -> 135 or -135 -> -45 */
+ if (y >= 0.0) { /* 45 -> 135 */
+ angle = 1.57079632679489661923;
+ if (x >= 0.0)
+ angle -= base_angle; /* 45 -> 90, angle = 90 - angle */
+ else
+ angle += base_angle; /* 90 -> 135, angle = 90 + angle */
+ } else { /* -135 -> -45 */
+ angle = -1.57079632679489661923;
+ if (x >= 0.0)
+ angle += base_angle; /* -90 -> -45, angle = -90 + angle */
+ else
+ angle -= base_angle; /* -135 -> -90, angle = -90 - angle */
+ }
+ }
+
+#ifdef ZERO_TO_TWOPI
+ if (angle < 0)
+ return (angle + TWOPI);
+ else
+ return (angle);
+#else
+ return (angle);
+#endif
+}
diff --git a/gnuradio-core/src/lib/general/gr_feval.cc b/gnuradio-core/src/lib/general/gr_feval.cc
new file mode 100644
index 0000000000..b30930ecba
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_feval.cc
@@ -0,0 +1,86 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_feval.h>
+
+gr_feval_dd::~gr_feval_dd(){}
+
+double
+gr_feval_dd::eval(double x)
+{
+ return 0;
+}
+
+gr_feval_ff::~gr_feval_ff(){}
+
+float
+gr_feval_ff::eval(float x)
+{
+ return 0;
+}
+
+gr_feval_cc::~gr_feval_cc(){}
+
+gr_complex
+gr_feval_cc::eval(gr_complex x)
+{
+ return 0;
+}
+
+gr_feval_ll::~gr_feval_ll(){}
+
+long
+gr_feval_ll::eval(long x)
+{
+ return 0;
+}
+
+/*
+ * Trivial examples showing C++ (transparently) calling Python
+ */
+double
+gr_feval_dd_example(gr_feval_dd *f, double x)
+{
+ return f->eval(x);
+}
+
+float
+gr_feval_ff_example(gr_feval_ff *f, float x)
+{
+ return f->eval(x);
+}
+
+gr_complex
+gr_feval_cc_example(gr_feval_cc *f, gr_complex x)
+{
+ return f->eval(x);
+}
+
+long
+gr_feval_ll_example(gr_feval_ll *f, long x)
+{
+ return f->eval(x);
+}
diff --git a/gnuradio-core/src/lib/general/gr_feval.h b/gnuradio-core/src/lib/general/gr_feval.h
new file mode 100644
index 0000000000..e9f3ae3506
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_feval.h
@@ -0,0 +1,116 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_FEVAL_H
+#define INCLUDED_GR_FEVAL_H
+
+#include <gr_complex.h>
+
+/*!
+ * \brief base class for evaluating a function: double -> double
+ *
+ * This class is designed to be subclassed in Python or C++
+ * and is callable from both places. It uses SWIG's
+ * "director" feature to implement the magic.
+ * It's slow. Don't use it in a performance critical path.
+ */
+class gr_feval_dd
+{
+public:
+ gr_feval_dd() {}
+ virtual ~gr_feval_dd();
+
+ /*!
+ * \brief override this to define the function
+ */
+ virtual double eval(double x);
+};
+
+/*!
+ * \brief base class for evaluating a function: float -> float
+ *
+ * This class is designed to be subclassed in Python or C++
+ * and is callable from both places. It uses SWIG's
+ * "director" feature to implement the magic.
+ * It's slow. Don't use it in a performance critical path.
+ */
+class gr_feval_ff
+{
+public:
+ gr_feval_ff() {}
+ virtual ~gr_feval_ff();
+
+ /*!
+ * \brief override this to define the function
+ */
+ virtual float eval(float x);
+};
+
+/*!
+ * \brief base class for evaluating a function: complex -> complex
+ *
+ * This class is designed to be subclassed in Python or C++
+ * and is callable from both places. It uses SWIG's
+ * "director" feature to implement the magic.
+ * It's slow. Don't use it in a performance critical path.
+ */
+class gr_feval_cc
+{
+public:
+ gr_feval_cc() {}
+ virtual ~gr_feval_cc();
+
+ /*!
+ * \brief override this to define the function
+ */
+ virtual gr_complex eval(gr_complex x);
+};
+
+/*!
+ * \brief base class for evaluating a function: long -> long
+ *
+ * This class is designed to be subclassed in Python or C++
+ * and is callable from both places. It uses SWIG's
+ * "director" feature to implement the magic.
+ * It's slow. Don't use it in a performance critical path.
+ */
+class gr_feval_ll
+{
+public:
+ gr_feval_ll() {}
+ virtual ~gr_feval_ll();
+
+ /*!
+ * \brief override this to define the function
+ */
+ virtual long eval(long x);
+};
+
+/*!
+ * \brief trivial examples / test cases showing C++ calling Python code
+ */
+double gr_feval_dd_example(gr_feval_dd *f, double x);
+float gr_feval_ff_example(gr_feval_ff *f, float x);
+gr_complex gr_feval_cc_example(gr_feval_cc *f, gr_complex x);
+long gr_feval_ll_example(gr_feval_ll *f, long x);
+
+
+#endif /* INCLUDED_GR_FEVAL_H */
diff --git a/gnuradio-core/src/lib/general/gr_feval.i b/gnuradio-core/src/lib/general/gr_feval.i
new file mode 100644
index 0000000000..f7d8c2219a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_feval.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// Enable SWIG directors for these classes
+%feature("director") gr_feval_dd;
+%feature("director") gr_feval_cc;
+%feature("director") gr_feval_ll;
+
+
+%rename(feval_dd) gr_feval_dd;
+class gr_feval_dd
+{
+public:
+ gr_feval_dd() {}
+ virtual ~gr_feval_dd();
+
+ virtual double eval(double x);
+};
+
+%rename(feval_cc) gr_feval_cc;
+class gr_feval_cc
+{
+public:
+ gr_feval_cc() {}
+ virtual ~gr_feval_cc();
+
+ virtual gr_complex eval(gr_complex x);
+};
+
+%rename(feval_ll) gr_feval_ll;
+class gr_feval_ll
+{
+public:
+ gr_feval_ll() {}
+ virtual ~gr_feval_ll();
+
+ virtual long eval(long x);
+};
+
+
+// examples / test cases
+
+%rename(feval_dd_example) gr_feval_dd_example;
+double gr_feval_dd_example(gr_feval_dd *f, double x);
+
+%rename(feval_cc_example) gr_feval_cc_example;
+gr_complex gr_feval_cc_example(gr_feval_cc *f, gr_complex x);
+
+%rename(feval_ll_example) gr_feval_ll_example;
+long gr_feval_ll_example(gr_feval_ll *f, long x);
diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc.cc b/gnuradio-core/src/lib/general/gr_fft_vcc.cc
new file mode 100644
index 0000000000..e529159081
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fft_vcc.cc
@@ -0,0 +1,102 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_fft_vcc.h>
+#include <gr_io_signature.h>
+#include <gri_fft.h>
+#include <math.h>
+
+gr_fft_vcc_sptr
+gr_make_fft_vcc (int fft_size, bool forward,const std::vector<float> window)
+{
+ return gr_fft_vcc_sptr (new gr_fft_vcc (fft_size, forward, window));
+}
+
+gr_fft_vcc::gr_fft_vcc (int fft_size, bool forward, const std::vector<float> window)
+ : gr_sync_block ("fft_vcc",
+ gr_make_io_signature (1, 1, fft_size * sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, fft_size * sizeof (gr_complex))),
+ d_fft_size(fft_size)
+{
+ d_fft = new gri_fft_complex (d_fft_size, forward);
+
+ set_window(window);
+
+}
+
+gr_fft_vcc::~gr_fft_vcc ()
+{
+ delete d_fft;
+}
+
+int
+gr_fft_vcc::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *in = (const gr_complex *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ unsigned int input_data_size = input_signature()->sizeof_stream_item (0);
+ unsigned int output_data_size = output_signature()->sizeof_stream_item (0);
+
+ int count = 0;
+
+ while (count++ < noutput_items){
+
+ // copy input into optimally aligned buffer
+
+ if (d_window.size()){
+ gr_complex *dst = d_fft->get_inbuf();
+ for (unsigned int i = 0; i < d_fft_size; i++) // apply window
+ dst[i] = in[i] * d_window[i];
+ }
+ else
+ memcpy (d_fft->get_inbuf(), in, input_data_size);
+
+ // compute the fft
+ d_fft->execute ();
+
+ // cpoy result to our output
+ memcpy (out, d_fft->get_outbuf (), output_data_size);
+
+ in += d_fft_size;
+ out += d_fft_size;
+ }
+
+ return noutput_items;
+}
+
+bool
+gr_fft_vcc::set_window(const std::vector<float> window)
+{
+ if(window.size()==0 || window.size()==d_fft_size) {
+ d_window=window;
+ return true;
+ }
+ else
+ return false;
+}
diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc.h b/gnuradio-core/src/lib/general/gr_fft_vcc.h
new file mode 100644
index 0000000000..784471a316
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fft_vcc.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_FFT_VCC_H
+#define INCLUDED_GR_FFT_VCC_H
+
+#include <gr_sync_block.h>
+
+class gri_fft_complex;
+
+class gr_fft_vcc;
+typedef boost::shared_ptr<gr_fft_vcc> gr_fft_vcc_sptr;
+
+gr_fft_vcc_sptr
+gr_make_fft_vcc (int fft_size, bool forward, const std::vector<float> window);
+
+/*!
+ * \brief Compute forward or reverse FFT. complex vector in / complex vector out.
+ * \ingroup block
+ */
+
+class gr_fft_vcc : public gr_sync_block
+{
+ friend gr_fft_vcc_sptr
+ gr_make_fft_vcc (int fft_size, bool forward, const std::vector<float> window);
+
+ unsigned int d_fft_size;
+ std::vector<float> d_window;
+ gri_fft_complex *d_fft;
+
+ gr_fft_vcc (int fft_size, bool forward, const std::vector<float> window);
+
+ public:
+ ~gr_fft_vcc ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ bool set_window(const std::vector<float> window);
+};
+
+
+#endif /* INCLUDED_GR_FFT_VCC_H */
diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc.i b/gnuradio-core/src/lib/general/gr_fft_vcc.i
new file mode 100644
index 0000000000..a171d122ba
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fft_vcc.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr, fft_vcc)
+
+gr_fft_vcc_sptr
+gr_make_fft_vcc (int fft_size, bool forward, const std::vector<float> window);
+
+class gr_fft_vcc : public gr_sync_block
+{
+ protected:
+ gr_fft_vcc (int fft_size, bool forward, const std::vector<float> window);
+
+ public:
+ bool set_window(const std::vector<float> window);
+};
diff --git a/gnuradio-core/src/lib/general/gr_fft_vfc.cc b/gnuradio-core/src/lib/general/gr_fft_vfc.cc
new file mode 100644
index 0000000000..d6d2479114
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fft_vfc.cc
@@ -0,0 +1,116 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_fft_vfc.h>
+#include <gr_io_signature.h>
+#include <gri_fft.h>
+#include <math.h>
+#include <stdexcept>
+
+
+// FIXME after this is working, change to use native real to complex fft.
+// It should run twice as fast.
+
+
+
+
+gr_fft_vfc_sptr
+gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float> window)
+{
+ return gr_fft_vfc_sptr (new gr_fft_vfc (fft_size, forward, window));
+}
+
+gr_fft_vfc::gr_fft_vfc (int fft_size, bool forward, const std::vector<float> window)
+ : gr_sync_block ("fft_vfc",
+ gr_make_io_signature (1, 1, fft_size * sizeof (float)),
+ gr_make_io_signature (1, 1, fft_size * sizeof (gr_complex))),
+ d_fft_size(fft_size), d_window()
+{
+ if (!forward){
+ fprintf (stderr, "fft_vfc: forward must == true\n");
+ throw std::invalid_argument ("fft_vfc: forward must == true");
+ }
+
+ d_fft = new gri_fft_complex (d_fft_size, forward);
+
+ set_window(window);
+}
+
+gr_fft_vfc::~gr_fft_vfc ()
+{
+ delete d_fft;
+}
+
+int
+gr_fft_vfc::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ unsigned int output_data_size = output_signature()->sizeof_stream_item (0);
+
+ int count = 0;
+
+ while (count++ < noutput_items){
+
+ // copy input into optimally aligned buffer
+
+ if (d_window.size()){
+ gr_complex *dst = d_fft->get_inbuf();
+ for (unsigned int i = 0; i < d_fft_size; i++) // apply window
+ dst[i] = in[i] * d_window[i];
+ }
+ else {
+ gr_complex *dst = d_fft->get_inbuf();
+ for (unsigned int i = 0; i < d_fft_size; i++) // float to complex conversion
+ dst[i] = in[i];
+ }
+
+ // compute the fft
+ d_fft->execute ();
+
+ // cpoy result to our output
+ memcpy (out, d_fft->get_outbuf (), output_data_size);
+
+ in += d_fft_size;
+ out += d_fft_size;
+ }
+
+ return noutput_items;
+}
+
+bool
+gr_fft_vfc::set_window(const std::vector<float> window)
+{
+ if(window.size()==0 || window.size()==d_fft_size) {
+ d_window=window;
+ return true;
+ }
+ else
+ return false;
+}
diff --git a/gnuradio-core/src/lib/general/gr_fft_vfc.h b/gnuradio-core/src/lib/general/gr_fft_vfc.h
new file mode 100644
index 0000000000..a30495d8ff
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fft_vfc.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_FFT_VFC_H
+#define INCLUDED_GR_FFT_VFC_H
+
+#include <gr_sync_block.h>
+
+class gri_fft_complex;
+
+class gr_fft_vfc;
+typedef boost::shared_ptr<gr_fft_vfc> gr_fft_vfc_sptr;
+
+gr_fft_vfc_sptr
+gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float>);
+
+/*!
+ * \brief Compute forward FFT. float vector in / complex vector out.
+ * \ingroup block
+ */
+
+class gr_fft_vfc : public gr_sync_block
+{
+ friend gr_fft_vfc_sptr
+ gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float> window);
+
+ unsigned int d_fft_size;
+ std::vector<float> d_window;
+ gri_fft_complex *d_fft;
+
+ gr_fft_vfc (int fft_size, bool forward, const std::vector<float> window);
+
+ public:
+ ~gr_fft_vfc ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ bool set_window(const std::vector<float> window);
+};
+
+
+#endif /* INCLUDED_GR_FFT_VFC_H */
diff --git a/gnuradio-core/src/lib/general/gr_fft_vfc.i b/gnuradio-core/src/lib/general/gr_fft_vfc.i
new file mode 100644
index 0000000000..f30606d824
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fft_vfc.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr, fft_vfc)
+
+gr_fft_vfc_sptr
+gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float> window);
+
+class gr_fft_vfc : public gr_sync_block
+{
+ protected:
+ gr_fft_vfc (int fft_size, bool forward, const std::vector<float> window);
+
+ public:
+ bool set_window(const std::vector<float> window);
+};
diff --git a/gnuradio-core/src/lib/general/gr_firdes.cc b/gnuradio-core/src/lib/general/gr_firdes.cc
new file mode 100644
index 0000000000..d09d68d610
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_firdes.cc
@@ -0,0 +1,584 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gr_firdes.h>
+#include <stdexcept>
+
+
+using std::vector;
+
+#define IzeroEPSILON 1E-21 /* Max error acceptable in Izero */
+
+static double Izero(double x)
+{
+ double sum, u, halfx, temp;
+ int n;
+
+ sum = u = n = 1;
+ halfx = x/2.0;
+ do {
+ temp = halfx/(double)n;
+ n += 1;
+ temp *= temp;
+ u *= temp;
+ sum += u;
+ } while (u >= IzeroEPSILON*sum);
+ return(sum);
+}
+
+
+//
+// === Low Pass ===
+//
+
+vector<float>
+gr_firdes::low_pass (double gain,
+ double sampling_freq,
+ double cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ win_type window_type,
+ double beta) // used only with Kaiser
+{
+ sanity_check_1f (sampling_freq, cutoff_freq, transition_width);
+
+ int ntaps = compute_ntaps (sampling_freq, transition_width,
+ window_type, beta);
+
+ // construct the truncated ideal impulse response
+ // [sin(x)/x for the low pass case]
+
+ vector<float> taps(ntaps);
+ vector<float> w = window (window_type, ntaps, beta);
+
+ int M = (ntaps - 1) / 2;
+ double fwT0 = 2 * M_PI * cutoff_freq / sampling_freq;
+
+ for (int n = -M; n <= M; n++){
+ if (n == 0)
+ taps[n + M] = fwT0 / M_PI * w[n + M];
+ else {
+ // a little algebra gets this into the more familiar sin(x)/x form
+ taps[n + M] = sin (n * fwT0) / (n * M_PI) * w[n + M];
+ }
+ }
+
+ // find the factor to normalize the gain, fmax.
+ // For low-pass, gain @ zero freq = 1.0
+
+ double fmax = taps[0 + M];
+ for (int n = 1; n <= M; n++)
+ fmax += 2 * taps[n + M];
+
+ gain /= fmax; // normalize
+
+ for (int i = 0; i < ntaps; i++)
+ taps[i] *= gain;
+
+ return taps;
+}
+
+//
+// === High Pass ===
+//
+
+vector<float>
+gr_firdes::high_pass (double gain,
+ double sampling_freq,
+ double cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ win_type window_type,
+ double beta) // used only with Kaiser
+{
+ sanity_check_1f (sampling_freq, cutoff_freq, transition_width);
+
+ int ntaps = compute_ntaps (sampling_freq, transition_width,
+ window_type, beta);
+
+ // construct the truncated ideal impulse response times the window function
+
+ vector<float> taps(ntaps);
+ vector<float> w = window (window_type, ntaps, beta);
+
+ int M = (ntaps - 1) / 2;
+ double fwT0 = 2 * M_PI * cutoff_freq / sampling_freq;
+
+ for (int n = -M; n <= M; n++){
+ if (n == 0)
+ taps[n + M] = (1 - (fwT0 / M_PI)) * w[n + M];
+ else {
+ // a little algebra gets this into the more familiar sin(x)/x form
+ taps[n + M] = -sin (n * fwT0) / (n * M_PI) * w[n + M];
+ }
+ }
+
+ // find the factor to normalize the gain, fmax.
+ // For high-pass, gain @ fs/2 freq = 1.0
+
+ double fmax = taps[0 + M];
+ for (int n = 1; n <= M; n++)
+ fmax += 2 * taps[n + M] * cos (n * M_PI);
+
+ gain /= fmax; // normalize
+
+ for (int i = 0; i < ntaps; i++)
+ taps[i] *= gain;
+
+ return taps;
+}
+
+//
+// === Band Pass ===
+//
+
+vector<float>
+gr_firdes::band_pass (double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz center of transition band
+ double high_cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ win_type window_type,
+ double beta) // used only with Kaiser
+{
+ sanity_check_2f (sampling_freq,
+ low_cutoff_freq,
+ high_cutoff_freq, transition_width);
+
+ int ntaps = compute_ntaps (sampling_freq, transition_width,
+ window_type, beta);
+
+ // construct the truncated ideal impulse response times the window function
+
+ vector<float> taps(ntaps);
+ vector<float> w = window (window_type, ntaps, beta);
+
+ int M = (ntaps - 1) / 2;
+ double fwT0 = 2 * M_PI * low_cutoff_freq / sampling_freq;
+ double fwT1 = 2 * M_PI * high_cutoff_freq / sampling_freq;
+
+ for (int n = -M; n <= M; n++){
+ if (n == 0)
+ taps[n + M] = (fwT1 - fwT0) / M_PI * w[n + M];
+ else {
+ taps[n + M] = (sin (n * fwT1) - sin (n * fwT0)) / (n * M_PI) * w[n + M];
+ }
+ }
+
+ // find the factor to normalize the gain, fmax.
+ // For band-pass, gain @ center freq = 1.0
+
+ double fmax = taps[0 + M];
+ for (int n = 1; n <= M; n++)
+ fmax += 2 * taps[n + M] * cos (n * (fwT0 + fwT1) * 0.5);
+
+ gain /= fmax; // normalize
+
+ for (int i = 0; i < ntaps; i++)
+ taps[i] *= gain;
+
+ return taps;
+}
+
+//
+// === Complex Band Pass ===
+//
+
+vector<gr_complex>
+gr_firdes::complex_band_pass (double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz center of transition band
+ double high_cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ win_type window_type,
+ double beta) // used only with Kaiser
+{
+ sanity_check_2f_c (sampling_freq,
+ low_cutoff_freq,
+ high_cutoff_freq, transition_width);
+
+ int ntaps = compute_ntaps (sampling_freq, transition_width,
+ window_type, beta);
+
+ // construct the truncated ideal impulse response times the window function
+
+ vector<gr_complex> taps(ntaps);
+ vector<float> lptaps(ntaps);
+ vector<float> w = window (window_type, ntaps, beta);
+
+ lptaps = low_pass(gain,sampling_freq,(high_cutoff_freq - low_cutoff_freq)/2,transition_width,window_type,beta);
+
+ gr_complex *optr = &taps[0];
+ float *iptr = &lptaps[0];
+ float freq = M_PI * (high_cutoff_freq + low_cutoff_freq)/sampling_freq;
+ float phase=0;
+ if (lptaps.size() & 01) {
+ phase = - freq * ( lptaps.size() >> 1 );
+ } else phase = - freq/2.0 * ((1 + 2*lptaps.size()) >> 1);
+ for(unsigned int i=0;i<lptaps.size();i++) {
+ *optr++ = gr_complex(*iptr * cos(phase),*iptr * sin(phase));
+ iptr++, phase += freq;
+ }
+
+ return taps;
+}
+
+
+//
+// === Band Reject ===
+//
+
+vector<float>
+gr_firdes::band_reject (double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz center of transition band
+ double high_cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ win_type window_type,
+ double beta) // used only with Kaiser
+{
+ sanity_check_2f (sampling_freq,
+ low_cutoff_freq,
+ high_cutoff_freq, transition_width);
+
+ int ntaps = compute_ntaps (sampling_freq, transition_width,
+ window_type, beta);
+
+ // construct the truncated ideal impulse response times the window function
+
+ vector<float> taps(ntaps);
+ vector<float> w = window (window_type, ntaps, beta);
+
+ int M = (ntaps - 1) / 2;
+ double fwT0 = 2 * M_PI * low_cutoff_freq / sampling_freq;
+ double fwT1 = 2 * M_PI * high_cutoff_freq / sampling_freq;
+
+ for (int n = -M; n <= M; n++){
+ if (n == 0)
+ taps[n + M] = (1.0 + (fwT0 - fwT1)) / M_PI * w[n + M];
+ else {
+ taps[n + M] = (sin (n * fwT0) - sin (n * fwT1)) / (n * M_PI) * w[n + M];
+ }
+ }
+
+ // find the factor to normalize the gain, fmax.
+ // For band-reject, gain @ zero freq = 1.0
+
+ double fmax = taps[0 + M];
+ for (int n = 1; n <= M; n++)
+ fmax += 2 * taps[n + M];
+
+ gain /= fmax; // normalize
+
+ for (int i = 0; i < ntaps; i++)
+ taps[i] *= gain;
+
+ return taps;
+}
+
+//
+// Hilbert Transform
+//
+
+vector<float>
+gr_firdes::hilbert (unsigned int ntaps,
+ win_type windowtype,
+ double beta)
+{
+ if(!(ntaps & 1))
+ throw std::out_of_range("Hilbert: Must have odd number of taps");
+
+ vector<float> taps(ntaps);
+ vector<float> w = window (windowtype, ntaps, beta);
+ unsigned int h = (ntaps-1)/2;
+ float gain=0;
+ for (unsigned int i = 1; i <= h; i++)
+ {
+ if(i&1)
+ {
+ float x = 1/(float)i;
+ taps[h+i] = x * w[h+i];
+ taps[h-i] = -x * w[h-i];
+ gain = taps[h+i] - gain;
+ }
+ else
+ taps[h+i] = taps[h-i] = 0;
+ }
+ gain = 2 * fabs(gain);
+ for ( unsigned int i = 0; i < ntaps; i++)
+ taps[i] /= gain;
+ return taps;
+}
+
+//
+// Gaussian
+//
+
+vector<float>
+gr_firdes::gaussian (double gain,
+ double spb,
+ double bt,
+ int ntaps)
+{
+
+ vector<float> taps(ntaps);
+ double scale = 0;
+ double dt = 1.0/spb;
+ double s = 1.0/(sqrt(log(2)) / (2*M_PI*bt));
+ double t0 = -0.5 * ntaps;
+ double ts;
+ for(int i=0;i<ntaps;i++)
+ {
+ t0++;
+ ts = s*dt*t0;
+ taps[i] = exp(-0.5*ts*ts);
+ scale += taps[i];
+ }
+ for(int i=0;i<ntaps;i++)
+ taps[i] = taps[i] / scale * gain;
+ return taps;
+}
+
+
+//
+// Root Raised Cosine
+//
+
+vector<float>
+gr_firdes::root_raised_cosine (double gain,
+ double sampling_freq,
+ double symbol_rate,
+ double alpha,
+ int ntaps)
+{
+ ntaps |= 1; // ensure that ntaps is odd
+
+ double spb = sampling_freq/symbol_rate; // samples per bit/symbol
+ vector<float> taps(ntaps);
+ double scale = 0;
+ for(int i=0;i<ntaps;i++)
+ {
+ double x1,x2,x3,num,den;
+ double xindx = i - ntaps/2;
+ x1 = M_PI * xindx/spb;
+ x2 = 4 * alpha * xindx / spb;
+ x3 = x2*x2 - 1;
+ if( fabs(x3) >= 0.000001 ) // Avoid Rounding errors...
+ {
+ if( i != ntaps/2 )
+ num = cos((1+alpha)*x1) + sin((1-alpha)*x1)/(4*alpha*xindx/spb);
+ else
+ num = cos((1+alpha)*x1) + (1-alpha) * M_PI / (4*alpha);
+ den = x3 * M_PI;
+ }
+ else
+ {
+ if(alpha==1)
+ {
+ taps[i] = -1;
+ continue;
+ }
+ x3 = (1-alpha)*x1;
+ x2 = (1+alpha)*x1;
+ num = (sin(x2)*(1+alpha)*M_PI
+ - cos(x3)*((1-alpha)*M_PI*spb)/(4*alpha*xindx)
+ + sin(x3)*spb*spb/(4*alpha*xindx*xindx));
+ den = -32 * M_PI * alpha * alpha * xindx/spb;
+ }
+ taps[i] = 4 * alpha * num / den;
+ scale += taps[i];
+ }
+
+ for(int i=0;i<ntaps;i++)
+ taps[i] = taps[i] * gain / scale;
+
+ return taps;
+}
+
+//
+// === Utilities ===
+//
+
+// delta_f / width_factor gives number of taps required.
+static const float width_factor[5] = { // indexed by win_type
+ 3.3, // WIN_HAMMING
+ 3.1, // WIN_HANN
+ 5.5, // WIN_BLACKMAN
+ 2.0, // WIN_RECTANGULAR
+ //5.0 // WIN_KAISER (guesstimate compromise)
+ //2.0 // WIN_KAISER (guesstimate compromise)
+ 10.0 // WIN_KAISER
+};
+
+int
+gr_firdes::compute_ntaps (double sampling_freq,
+ double transition_width,
+ win_type window_type,
+ double beta)
+{
+ // normalized transition width
+ double delta_f = transition_width / sampling_freq;
+
+ // compute number of taps required for given transition width
+ int ntaps = (int) (width_factor[window_type] / delta_f + 0.5);
+ if ((ntaps & 1) == 0) // if even...
+ ntaps++; // ...make odd
+
+ return ntaps;
+}
+
+double gr_firdes::bessi0(double x)
+{
+ double ax,ans;
+ double y;
+
+ ax=fabs(x);
+ if (ax < 3.75)
+ {
+ y=x/3.75;
+ y*=y;
+ ans=1.0+y*(3.5156229+y*(3.0899424+y*(1.2067492
+ +y*(0.2659732+y*(0.360768e-1+y*0.45813e-2)))));
+ }
+ else
+ {
+ y=3.75/ax;
+ ans=(exp(ax)/sqrt(ax))*(0.39894228+y*(0.1328592e-1
+ +y*(0.225319e-2+y*(-0.157565e-2+y*(0.916281e-2
+ +y*(-0.2057706e-1+y*(0.2635537e-1+y*(-0.1647633e-1
+ +y*0.392377e-2))))))));
+ }
+ return ans;
+}
+vector<float>
+gr_firdes::window (win_type type, int ntaps, double beta)
+{
+ vector<float> taps(ntaps);
+ int M = ntaps - 1; // filter order
+
+ switch (type){
+ case WIN_RECTANGULAR:
+ for (int n = 0; n < ntaps; n++)
+ taps[n] = 1;
+
+ case WIN_HAMMING:
+ for (int n = 0; n < ntaps; n++)
+ taps[n] = 0.54 - 0.46 * cos ((2 * M_PI * n) / M);
+ break;
+
+ case WIN_HANN:
+ for (int n = 0; n < ntaps; n++)
+ taps[n] = 0.5 - 0.5 * cos ((2 * M_PI * n) / M);
+ break;
+
+ case WIN_BLACKMAN:
+ for (int n = 0; n < ntaps; n++)
+ taps[n] = 0.42 - 0.50 * cos ((2*M_PI * n) / (M-1)) - 0.08 * cos ((4*M_PI * n) / (M-1));
+ break;
+
+#if 0
+ case WIN_KAISER:
+ for (int n = 0; n < ntaps; n++)
+ taps[n] = bessi0(beta*sqrt(1.0 - (4.0*n/(M*M))))/bessi0(beta);
+ break;
+#else
+
+ case WIN_KAISER:
+ {
+ double IBeta = 1.0/Izero(beta);
+ double inm1 = 1.0/((double)(ntaps));
+ double temp;
+ //fprintf(stderr, "IBeta = %g; inm1 = %g\n", IBeta, inm1);
+
+ for (int i=0; i<ntaps; i++) {
+ temp = i * inm1;
+ //fprintf(stderr, "temp = %g\n", temp);
+ taps[i] = Izero(beta*sqrt(1.0-temp*temp)) * IBeta;
+ //fprintf(stderr, "taps[%d] = %g\n", i, taps[i]);
+ }
+ }
+ break;
+
+#endif
+ default:
+ throw std::runtime_error ("not_implemented");
+ }
+
+ return taps;
+}
+
+void
+gr_firdes::sanity_check_1f (double sampling_freq,
+ double fa, // cutoff freq
+ double transition_width)
+{
+ if (sampling_freq <= 0.0)
+ throw std::out_of_range ("gr_firdes check failed: sampling_freq > 0");
+
+ if (fa <= 0.0 || fa > sampling_freq / 2)
+ throw std::out_of_range ("gr_firdes check failed: 0 < fa <= sampling_freq / 2");
+
+ if (transition_width <= 0)
+ throw std::out_of_range ("gr_dirdes check failed: transition_width > 0");
+}
+
+void
+gr_firdes::sanity_check_2f (double sampling_freq,
+ double fa, // first cutoff freq
+ double fb, // second cutoff freq
+ double transition_width)
+{
+ if (sampling_freq <= 0.0)
+ throw std::out_of_range ("gr_firdes check failed: sampling_freq > 0");
+
+ if (fa <= 0.0 || fa > sampling_freq / 2)
+ throw std::out_of_range ("gr_firdes check failed: 0 < fa <= sampling_freq / 2");
+
+ if (fb <= 0.0 || fb > sampling_freq / 2)
+ throw std::out_of_range ("gr_firdes check failed: 0 < fb <= sampling_freq / 2");
+
+ if (fa > fb)
+ throw std::out_of_range ("gr_firdes check failed: fa <= fb");
+
+ if (transition_width <= 0)
+ throw std::out_of_range ("gr_firdes check failed: transition_width > 0");
+}
+
+void
+gr_firdes::sanity_check_2f_c (double sampling_freq,
+ double fa, // first cutoff freq
+ double fb, // second cutoff freq
+ double transition_width)
+{
+ if (sampling_freq <= 0.0)
+ throw std::out_of_range ("gr_firdes check failed: sampling_freq > 0");
+
+ if (fa < -sampling_freq / 2 || fa > sampling_freq / 2)
+ throw std::out_of_range ("gr_firdes check failed: 0 < fa <= sampling_freq / 2");
+
+ if (fb < -sampling_freq / 2 || fb > sampling_freq / 2)
+ throw std::out_of_range ("gr_firdes check failed: 0 < fb <= sampling_freq / 2");
+
+ if (fa > fb)
+ throw std::out_of_range ("gr_firdes check failed: fa <= fb");
+
+ if (transition_width <= 0)
+ throw std::out_of_range ("gr_firdes check failed: transition_width > 0");
+}
diff --git a/gnuradio-core/src/lib/general/gr_firdes.h b/gnuradio-core/src/lib/general/gr_firdes.h
new file mode 100644
index 0000000000..734f8ee9fe
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_firdes.h
@@ -0,0 +1,225 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GR_FIRDES_H_
+#define _GR_FIRDES_H_
+
+#include <vector>
+#include <cmath>
+#include <gr_complex.h>
+
+/*!
+ * \brief Finite Impulse Response (FIR) filter design functions.
+ */
+
+class gr_firdes {
+ public:
+
+ enum win_type {
+ WIN_HAMMING = 0, // max attenuation 53 dB
+ WIN_HANN = 1, // max attenuation 44 dB
+ WIN_BLACKMAN = 2, // max attenuation 74 dB
+ WIN_RECTANGULAR = 3,
+ WIN_KAISER = 4 // max attenuation a function of beta, google it
+ };
+
+
+ // ... class methods ...
+
+ /*!
+ * \brief use "window method" to design a low-pass FIR filter
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p sampling_freq: sampling freq (Hz)
+ * \p cutoff_freq: center of transition band (Hz)
+ * \p transition_width: width of transition band (Hz).
+ * The normalized width of the transition
+ * band is what sets the number of taps
+ * required. Narrow --> more taps
+ * \p window_type: What kind of window to use. Determines
+ * maximum attenuation and passband ripple.
+ * \p beta: parameter for Kaiser window
+ */
+ static std::vector<float>
+ low_pass (double gain,
+ double sampling_freq,
+ double cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ win_type window = WIN_HAMMING,
+ double beta = 6.76); // used only with Kaiser
+
+ /*!
+ * \brief use "window method" to design a high-pass FIR filter
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p sampling_freq: sampling freq (Hz)
+ * \p cutoff_freq: center of transition band (Hz)
+ * \p transition_width: width of transition band (Hz).
+ * The normalized width of the transition
+ * band is what sets the number of taps
+ * required. Narrow --> more taps
+ * \p window_type: What kind of window to use. Determines
+ * maximum attenuation and passband ripple.
+ * \p beta: parameter for Kaiser window
+ */
+ static std::vector<float>
+ high_pass (double gain,
+ double sampling_freq,
+ double cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ win_type window = WIN_HAMMING,
+ double beta = 6.76); // used only with Kaiser
+
+ /*!
+ * \brief use "window method" to design a band-pass FIR filter
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p sampling_freq: sampling freq (Hz)
+ * \p low_cutoff_freq: center of transition band (Hz)
+ * \p high_cutoff_freq: center of transition band (Hz)
+ * \p transition_width: width of transition band (Hz).
+ * The normalized width of the transition
+ * band is what sets the number of taps
+ * required. Narrow --> more taps
+ * \p window_type: What kind of window to use. Determines
+ * maximum attenuation and passband ripple.
+ * \p beta: parameter for Kaiser window
+ */
+ static std::vector<float>
+ band_pass (double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz center of transition band
+ double high_cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ win_type window = WIN_HAMMING,
+ double beta = 6.76); // used only with Kaiser
+
+
+ /*!
+ * \brief use "window method" to design a complex band-pass FIR filter
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p sampling_freq: sampling freq (Hz)
+ * \p low_cutoff_freq: center of transition band (Hz)
+ * \p high_cutoff_freq: center of transition band (Hz)
+ * \p transition_width: width of transition band (Hz).
+ * The normalized width of the transition
+ * band is what sets the number of taps
+ * required. Narrow --> more taps
+ * \p window_type: What kind of window to use. Determines
+ * maximum attenuation and passband ripple.
+ * \p beta: parameter for Kaiser window
+ */
+
+ static std::vector<gr_complex>
+ complex_band_pass (double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz center of transition band
+ double high_cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ win_type window = WIN_HAMMING,
+ double beta = 6.76); // used only with Kaiser
+
+
+ /*!
+ * \brief use "window method" to design a band-reject FIR filter
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p sampling_freq: sampling freq (Hz)
+ * \p low_cutoff_freq: center of transition band (Hz)
+ * \p high_cutoff_freq: center of transition band (Hz)
+ * \p transition_width: width of transition band (Hz).
+ * The normalized width of the transition
+ * band is what sets the number of taps
+ * required. Narrow --> more taps
+ * \p window_type: What kind of window to use. Determines
+ * maximum attenuation and passband ripple.
+ * \p beta: parameter for Kaiser window
+ */
+
+ static std::vector<float>
+ band_reject (double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz center of transition band
+ double high_cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ win_type window = WIN_HAMMING,
+ double beta = 6.76); // used only with Kaiser
+
+ /*!\brief design a Hilbert Transform Filter
+ *
+ * \p ntaps: Number of taps, must be odd
+ * \p window_type: What kind of window to use
+ * \p beta: Only used for Kaiser
+ */
+ static std::vector<float>
+ hilbert (unsigned int ntaps,
+ win_type windowtype = WIN_RECTANGULAR,
+ double beta = 6.76);
+
+ /*!
+ * \brief design a Root Cosine FIR Filter (do we need a window?)
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p sampling_freq: sampling freq (Hz)
+ * \p symbol rate: symbol rate, must be a factor of sample rate
+ * \p alpha: excess bandwidth factor
+ * \p ntaps: number of taps
+ */
+ static std::vector<float>
+ root_raised_cosine (double gain,
+ double sampling_freq,
+ double symbol_rate, // Symbol rate, NOT bitrate (unless BPSK)
+ double alpha, // Excess Bandwidth Factor
+ int ntaps);
+
+ /*!
+ * \brief design a Gaussian filter
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p symbols per bit: symbol rate, must be a factor of sample rate
+ * \p ntaps: number of taps
+ */
+ static std::vector<float>
+ gaussian (double gain,
+ double spb,
+ double bt, // Bandwidth to bitrate ratio
+ int ntaps);
+
+ // window functions ...
+ static std::vector<float> window (win_type type, int ntaps, double beta);
+
+private:
+ static double bessi0(double x);
+ static void sanity_check_1f (double sampling_freq, double f1,
+ double transition_width);
+ static void sanity_check_2f (double sampling_freq, double f1, double f2,
+ double transition_width);
+ static void sanity_check_2f_c (double sampling_freq, double f1, double f2,
+ double transition_width);
+
+ static int compute_ntaps (double sampling_freq,
+ double transition_width,
+ win_type window_type, double beta);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_firdes.i b/gnuradio-core/src/lib/general/gr_firdes.i
new file mode 100644
index 0000000000..a0ea2f4533
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_firdes.i
@@ -0,0 +1,187 @@
+/* -*- C++ -*- */
+
+/*!
+ * \brief Finite Impulse Response (FIR) filter design functions.
+ */
+
+%rename(firdes) gr_firdes;
+
+class gr_firdes {
+ public:
+
+ enum win_type {
+ WIN_HAMMING = 0, // max attenuation 53 dB
+ WIN_HANN = 1, // max attenuation 44 dB
+ WIN_BLACKMAN = 2, // max attenuation 74 dB
+ WIN_RECTANGULAR = 3,
+ WIN_KAISER = 4 // max attenuation variable with beta, google it
+ };
+
+ // ... class methods ...
+
+ /*!
+ * \brief use "window method" to design a low-pass FIR filter
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p sampling_freq: sampling freq (Hz)
+ * \p cutoff_freq: center of transition band (Hz)
+ * \p transition_width: width of transition band (Hz).
+ * The normalized width of the transition
+ * band is what sets the number of taps
+ * required. Narrow --> more taps
+ * \p window_type: What kind of window to use. Determines
+ * maximum attenuation and passband ripple.
+ * \p beta: parameter for Kaiser window
+ */
+ static std::vector<float>
+ low_pass (double gain,
+ double sampling_freq,
+ double cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ win_type window = WIN_HAMMING,
+ double beta = 6.76); // used only with Kaiser
+
+ /*!
+ * \brief use "window method" to design a high-pass FIR filter
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p sampling_freq: sampling freq (Hz)
+ * \p cutoff_freq: center of transition band (Hz)
+ * \p transition_width: width of transition band (Hz).
+ * The normalized width of the transition
+ * band is what sets the number of taps
+ * required. Narrow --> more taps
+ * \p window_type: What kind of window to use. Determines
+ * maximum attenuation and passband ripple.
+ * \p beta: parameter for Kaiser window
+ */
+ static std::vector<float>
+ high_pass (double gain,
+ double sampling_freq,
+ double cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ win_type window = WIN_HAMMING,
+ double beta = 6.76); // used only with Kaiser
+
+ /*!
+ * \brief use "window method" to design a band-pass FIR filter
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p sampling_freq: sampling freq (Hz)
+ * \p low_cutoff_freq: center of transition band (Hz)
+ * \p high_cutoff_freq: center of transition band (Hz)
+ * \p transition_width: width of transition band (Hz).
+ * The normalized width of the transition
+ * band is what sets the number of taps
+ * required. Narrow --> more taps
+ * \p window_type: What kind of window to use. Determines
+ * maximum attenuation and passband ripple.
+ * \p beta: parameter for Kaiser window
+ */
+ static std::vector<float>
+ band_pass (double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz center of transition band
+ double high_cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ win_type window = WIN_HAMMING,
+ double beta = 6.76); // used only with Kaiser
+
+
+ /*!
+ * \brief use "window method" to design a band-reject FIR filter
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p sampling_freq: sampling freq (Hz)
+ * \p low_cutoff_freq: center of transition band (Hz)
+ * \p high_cutoff_freq: center of transition band (Hz)
+ * \p transition_width: width of transition band (Hz).
+ * The normalized width of the transition
+ * band is what sets the number of taps
+ * required. Narrow --> more taps
+ * \p window_type: What kind of window to use. Determines
+ * maximum attenuation and passband ripple.
+ * \p beta: parameter for Kaiser window
+ */
+
+ static std::vector<gr_complex>
+ complex_band_pass (double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz center of transition band
+ double high_cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ win_type window = WIN_HAMMING,
+ double beta = 6.76); // used only with Kaiser
+
+
+ /*!
+ * \brief use "window method" to design a band-reject FIR filter
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p sampling_freq: sampling freq (Hz)
+ * \p low_cutoff_freq: center of transition band (Hz)
+ * \p high_cutoff_freq: center of transition band (Hz)
+ * \p transition_width: width of transition band (Hz).
+ * The normalized width of the transition
+ * band is what sets the number of taps
+ * required. Narrow --> more taps
+ * \p window_type: What kind of window to use. Determines
+ * maximum attenuation and passband ripple.
+ * \p beta: parameter for Kaiser window
+ */
+
+ static std::vector<float>
+ band_reject (double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz center of transition band
+ double high_cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ win_type window = WIN_HAMMING,
+ double beta = 6.76); // used only with Kaiser
+
+ /*!\brief design a Hilbert Transform Filter
+ *
+ * \p ntaps: Number of taps, must be odd
+ * \p window_type: What kind of window to use
+ * \p beta: Only used for Kaiser
+ */
+ static std::vector<float>
+ hilbert (unsigned int ntaps,
+ win_type windowtype = WIN_RECTANGULAR,
+ double beta = 6.76);
+
+ /*!
+ * \brief design a Root Cosine FIR Filter (do we need a window?)
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p sampling_freq: sampling freq (Hz)
+ * \p symbol rate: symbol rate, must be a factor of sample rate
+ * \p alpha: excess bandwidth factor
+ * \p ntaps: number of taps
+ */
+ static std::vector<float>
+ root_raised_cosine (double gain,
+ double sampling_freq,
+ double symbol_rate, // Symbol rate, NOT bitrate (unless BPSK)
+ double alpha, // Excess Bandwidth Factor
+ int ntaps);
+
+ /*!
+ * \brief design a Gaussian filter
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p symbols per bit: symbol rate, must be a factor of sample rate
+ * \p bt: BT bandwidth time product
+ * \p ntaps: number of taps
+ */
+ static std::vector<float>
+ gaussian (double gain,
+ double spb,
+ double bt, // Bandwidth to bitrate ratio
+ int ntaps);
+
+ /*!
+ * Return window given type, ntaps and optional beta.
+ */
+ static std::vector<float> gr_firdes::window (win_type type, int ntaps, double beta);
+};
diff --git a/gnuradio-core/src/lib/general/gr_float_to_char.cc b/gnuradio-core/src/lib/general/gr_float_to_char.cc
new file mode 100644
index 0000000000..ed9538fc19
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_char.cc
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_float_to_char.h>
+#include <gr_io_signature.h>
+#include <gri_float_to_char.h>
+
+gr_float_to_char_sptr
+gr_make_float_to_char ()
+{
+ return gr_float_to_char_sptr (new gr_float_to_char ());
+}
+
+gr_float_to_char::gr_float_to_char ()
+ : gr_sync_block ("gr_float_to_char",
+ gr_make_io_signature (1, 1, sizeof (float)),
+ gr_make_io_signature (1, 1, sizeof (char)))
+{
+}
+
+int
+gr_float_to_char::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+ char *out = (char *) output_items[0];
+
+ gri_float_to_char (in, out, noutput_items);
+
+ return noutput_items;
+}
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_float_to_char.h b/gnuradio-core/src/lib/general/gr_float_to_char.h
new file mode 100644
index 0000000000..e1d0f9f0a1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_char.h
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_FLOAT_TO_CHAR_H
+#define INCLUDED_GR_FLOAT_TO_CHAR_H
+
+#include <gr_sync_block.h>
+
+class gr_float_to_char;
+typedef boost::shared_ptr<gr_float_to_char> gr_float_to_char_sptr;
+
+gr_float_to_char_sptr
+gr_make_float_to_char ();
+
+/*!
+ * \brief Convert stream of float to a stream of char
+ * \ingroup converter
+ */
+
+class gr_float_to_char : public gr_sync_block
+{
+ friend gr_float_to_char_sptr gr_make_float_to_char ();
+ gr_float_to_char ();
+
+ public:
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_FLOAT_TO_CHAR_H */
diff --git a/gnuradio-core/src/lib/general/gr_float_to_char.i b/gnuradio-core/src/lib/general/gr_float_to_char.i
new file mode 100644
index 0000000000..139439c3d5
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_char.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,float_to_char)
+
+gr_float_to_char_sptr gr_make_float_to_char ();
+
+class gr_float_to_char : public gr_sync_block
+{
+ gr_float_to_char ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_float_to_complex.cc b/gnuradio-core/src/lib/general/gr_float_to_complex.cc
new file mode 100644
index 0000000000..547d9173a8
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_complex.cc
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_float_to_complex.h>
+#include <gr_io_signature.h>
+
+gr_float_to_complex_sptr
+gr_make_float_to_complex ()
+{
+ return gr_float_to_complex_sptr (new gr_float_to_complex ());
+}
+
+gr_float_to_complex::gr_float_to_complex ()
+ : gr_sync_block ("gr_float_to_complex",
+ gr_make_io_signature (1, 2, sizeof (float)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex)))
+{
+}
+
+int
+gr_float_to_complex::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ float *r = (float *)input_items[0];
+ float *i = (float *)input_items[1];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ switch (input_items.size ()){
+ case 1:
+ for (int j = 0; j < noutput_items; j++)
+ out[j] = gr_complex (r[j], 0);
+ break;
+
+ case 2:
+ for (int j = 0; j < noutput_items; j++)
+ out[j] = gr_complex (r[j], i[j]);
+ break;
+
+ default:
+ assert (0);
+ }
+
+ return noutput_items;
+}
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_float_to_complex.h b/gnuradio-core/src/lib/general/gr_float_to_complex.h
new file mode 100644
index 0000000000..8c285217a1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_FLOAT_TO_COMPLEX_H
+#define INCLUDED_GR_FLOAT_TO_COMPLEX_H
+
+#include <gr_sync_block.h>
+#include <gr_complex.h>
+
+class gr_float_to_complex;
+typedef boost::shared_ptr<gr_float_to_complex> gr_float_to_complex_sptr;
+
+gr_float_to_complex_sptr
+gr_make_float_to_complex ();
+
+/*!
+ * \brief Convert 1 or 2 streams of float to a stream of gr_complex
+ * \ingroup converter
+ */
+
+class gr_float_to_complex : public gr_sync_block
+{
+ friend gr_float_to_complex_sptr gr_make_float_to_complex ();
+ gr_float_to_complex ();
+
+ public:
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_FLOAT_TO_COMPLEX_H */
diff --git a/gnuradio-core/src/lib/general/gr_float_to_complex.i b/gnuradio-core/src/lib/general/gr_float_to_complex.i
new file mode 100644
index 0000000000..4a6ea324be
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,float_to_complex)
+
+gr_float_to_complex_sptr gr_make_float_to_complex ();
+
+class gr_float_to_complex : public gr_sync_block
+{
+ gr_float_to_complex ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_float_to_short.cc b/gnuradio-core/src/lib/general/gr_float_to_short.cc
new file mode 100644
index 0000000000..171726b828
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_short.cc
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_float_to_short.h>
+#include <gr_io_signature.h>
+#include <gri_float_to_short.h>
+
+gr_float_to_short_sptr
+gr_make_float_to_short ()
+{
+ return gr_float_to_short_sptr (new gr_float_to_short ());
+}
+
+gr_float_to_short::gr_float_to_short ()
+ : gr_sync_block ("gr_float_to_short",
+ gr_make_io_signature (1, 1, sizeof (float)),
+ gr_make_io_signature (1, 1, sizeof (short)))
+{
+}
+
+int
+gr_float_to_short::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+ short *out = (short *) output_items[0];
+
+ gri_float_to_short (in, out, noutput_items);
+
+ return noutput_items;
+}
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_float_to_short.h b/gnuradio-core/src/lib/general/gr_float_to_short.h
new file mode 100644
index 0000000000..75fdd9439d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_short.h
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_FLOAT_TO_SHORT_H
+#define INCLUDED_GR_FLOAT_TO_SHORT_H
+
+#include <gr_sync_block.h>
+
+class gr_float_to_short;
+typedef boost::shared_ptr<gr_float_to_short> gr_float_to_short_sptr;
+
+gr_float_to_short_sptr
+gr_make_float_to_short ();
+
+/*!
+ * \brief Convert stream of float to a stream of short
+ * \ingroup converter
+ */
+
+class gr_float_to_short : public gr_sync_block
+{
+ friend gr_float_to_short_sptr gr_make_float_to_short ();
+ gr_float_to_short ();
+
+ public:
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_FLOAT_TO_SHORT_H */
diff --git a/gnuradio-core/src/lib/general/gr_float_to_short.i b/gnuradio-core/src/lib/general/gr_float_to_short.i
new file mode 100644
index 0000000000..10726bc8ac
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,float_to_short)
+
+gr_float_to_short_sptr gr_make_float_to_short ();
+
+class gr_float_to_short : public gr_sync_block
+{
+ gr_float_to_short ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_float_to_uchar.cc b/gnuradio-core/src/lib/general/gr_float_to_uchar.cc
new file mode 100644
index 0000000000..d940242728
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_uchar.cc
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_float_to_uchar.h>
+#include <gr_io_signature.h>
+#include <gri_float_to_uchar.h>
+
+gr_float_to_uchar_sptr
+gr_make_float_to_uchar ()
+{
+ return gr_float_to_uchar_sptr (new gr_float_to_uchar ());
+}
+
+gr_float_to_uchar::gr_float_to_uchar ()
+ : gr_sync_block ("gr_float_to_uchar",
+ gr_make_io_signature (1, 1, sizeof (float)),
+ gr_make_io_signature (1, 1, sizeof (unsigned char)))
+{
+}
+
+int
+gr_float_to_uchar::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+
+ gri_float_to_uchar (in, out, noutput_items);
+
+ return noutput_items;
+}
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_float_to_uchar.h b/gnuradio-core/src/lib/general/gr_float_to_uchar.h
new file mode 100644
index 0000000000..bab00c4292
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_uchar.h
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_FLOAT_TO_UCHAR_H
+#define INCLUDED_GR_FLOAT_TO_UCHAR_H
+
+#include <gr_sync_block.h>
+
+class gr_float_to_uchar;
+typedef boost::shared_ptr<gr_float_to_uchar> gr_float_to_uchar_sptr;
+
+gr_float_to_uchar_sptr
+gr_make_float_to_uchar ();
+
+/*!
+ * \brief Convert stream of float to a stream of unsigned char
+ * \ingroup converter
+ */
+
+class gr_float_to_uchar : public gr_sync_block
+{
+ friend gr_float_to_uchar_sptr gr_make_float_to_uchar ();
+ gr_float_to_uchar ();
+
+ public:
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_FLOAT_TO_UCHAR_H */
diff --git a/gnuradio-core/src/lib/general/gr_float_to_uchar.i b/gnuradio-core/src/lib/general/gr_float_to_uchar.i
new file mode 100644
index 0000000000..8c0ee58439
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,float_to_uchar)
+
+gr_float_to_uchar_sptr gr_make_float_to_uchar ();
+
+class gr_float_to_uchar : public gr_sync_block
+{
+ gr_float_to_uchar ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_framer_sink_1.cc b/gnuradio-core/src/lib/general/gr_framer_sink_1.cc
new file mode 100644
index 0000000000..c1afc434ba
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_framer_sink_1.cc
@@ -0,0 +1,175 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_framer_sink_1.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <stdexcept>
+
+#define VERBOSE 0
+
+inline void
+gr_framer_sink_1::enter_search()
+{
+ if (VERBOSE)
+ fprintf(stderr, "@ enter_search\n");
+
+ d_state = STATE_SYNC_SEARCH;
+}
+
+inline void
+gr_framer_sink_1::enter_have_sync()
+{
+ if (VERBOSE)
+ fprintf(stderr, "@ enter_have_sync\n");
+
+ d_state = STATE_HAVE_SYNC;
+ d_header = 0;
+ d_headerbitlen_cnt = 0;
+}
+
+inline void
+gr_framer_sink_1::enter_have_header(int payload_len)
+{
+ if (VERBOSE)
+ fprintf(stderr, "@ enter_have_header (payload_len = %d)\n", payload_len);
+
+ d_state = STATE_HAVE_HEADER;
+ d_packetlen = payload_len;
+ d_packetlen_cnt = 0;
+ d_packet_byte = 0;
+ d_packet_byte_index = 0;
+}
+
+gr_framer_sink_1_sptr
+gr_make_framer_sink_1(gr_msg_queue_sptr target_queue)
+{
+ return gr_framer_sink_1_sptr(new gr_framer_sink_1(target_queue));
+}
+
+
+gr_framer_sink_1::gr_framer_sink_1(gr_msg_queue_sptr target_queue)
+ : gr_sync_block ("framer_sink_1",
+ gr_make_io_signature (1, 1, sizeof(unsigned char)),
+ gr_make_io_signature (0, 0, 0)),
+ d_target_queue(target_queue)
+{
+ enter_search();
+}
+
+gr_framer_sink_1::~gr_framer_sink_1 ()
+{
+}
+
+int
+gr_framer_sink_1::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ int count=0;
+
+ if (VERBOSE)
+ fprintf(stderr,">>> Entering state machine\n");
+
+ while (count < noutput_items){
+ switch(d_state) {
+
+ case STATE_SYNC_SEARCH: // Look for flag indicating beginning of pkt
+ if (VERBOSE)
+ fprintf(stderr,"SYNC Search, noutput=%d\n", noutput_items);
+
+ while (count < noutput_items) {
+ if (in[count] & 0x2){ // Found it, set up for header decode
+ enter_have_sync();
+ break;
+ }
+ count++;
+ }
+ break;
+
+ case STATE_HAVE_SYNC:
+ if (VERBOSE)
+ fprintf(stderr,"Header Search bitcnt=%d, header=0x%08x\n",
+ d_headerbitlen_cnt, d_header);
+
+ while (count < noutput_items) { // Shift bits one at a time into header
+ d_header = (d_header << 1) | (in[count++] & 0x1);
+ if (++d_headerbitlen_cnt == HEADERBITLEN) {
+
+ if (VERBOSE)
+ fprintf(stderr, "got header: 0x%08x\n", d_header);
+
+ // we have a full header, check to see if it has been received properly
+ if (header_ok()){
+ int payload_len = header_payload_len();
+ if (payload_len <= MAX_PKT_LEN) // reasonable?
+ enter_have_header(payload_len); // yes.
+ else
+ enter_search(); // no.
+ }
+ else
+ enter_search(); // no.
+ break; // we're in a new state
+ }
+ }
+ break;
+
+ case STATE_HAVE_HEADER:
+ if (VERBOSE)
+ fprintf(stderr,"Packet Build\n");
+
+ while (count < noutput_items) { // shift bits into bytes of packet one at a time
+ d_packet_byte = (d_packet_byte << 1) | (in[count++] & 0x1);
+ if (d_packet_byte_index++ == 7) { // byte is full so move to next byte
+ d_packet[d_packetlen_cnt++] = d_packet_byte;
+ d_packet_byte_index = 0;
+
+ if (d_packetlen_cnt == d_packetlen){ // packet is filled
+
+ // build a message
+ gr_message_sptr msg = gr_make_message(0, 0, 0, d_packetlen_cnt);
+ memcpy(msg->msg(), d_packet, d_packetlen_cnt);
+
+ d_target_queue->insert_tail(msg); // send it
+ msg.reset(); // free it up
+
+ enter_search();
+ break;
+ }
+ }
+ }
+ break;
+
+ default:
+ assert(0);
+
+ } // switch
+
+ } // while
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_framer_sink_1.h b/gnuradio-core/src/lib/general/gr_framer_sink_1.h
new file mode 100644
index 0000000000..3e38aeedc0
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_framer_sink_1.h
@@ -0,0 +1,103 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_FRAMER_SINK_1_H
+#define INCLUDED_GR_FRAMER_SINK_1_H
+
+#include <gr_sync_block.h>
+#include <gr_msg_queue.h>
+
+class gr_framer_sink_1;
+typedef boost::shared_ptr<gr_framer_sink_1> gr_framer_sink_1_sptr;
+
+gr_framer_sink_1_sptr
+gr_make_framer_sink_1 (gr_msg_queue_sptr target_queue);
+
+/*!
+ * \brief Given a stream of bits and access_code flags, assemble packets.
+ * \ingroup sink
+ *
+ * input: stream of bytes from gr_correlate_access_code_bb
+ * output: none. Pushes assembled packet into target queue
+ *
+ * The framer expects a fixed length header of 2 16-bit shorts
+ * containing the payload length, followed by the payload. If the
+ * 2 16-bit shorts are not identical, this packet is ignored. Better
+ * algs are welcome.
+ *
+ * The input data consists of bytes that have two bits used.
+ * Bit 0, the LSB, contains the data bit.
+ * Bit 1 if set, indicates that the corresponding bit is the
+ * the first bit of the packet. That is, this bit is the first
+ * one after the access code.
+ */
+class gr_framer_sink_1 : public gr_sync_block
+{
+ friend gr_framer_sink_1_sptr
+ gr_make_framer_sink_1 (gr_msg_queue_sptr target_queue);
+
+ private:
+ enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER};
+
+ static const int MAX_PKT_LEN = 4096;
+ static const int HEADERBITLEN = 32;
+
+ gr_msg_queue_sptr d_target_queue; // where to send the packet when received
+ state_t d_state;
+ unsigned int d_header; // header bits
+ int d_headerbitlen_cnt; // how many so far
+
+ unsigned char d_packet[MAX_PKT_LEN]; // assembled payload
+ unsigned char d_packet_byte; // byte being assembled
+ int d_packet_byte_index; // which bit of d_packet_byte we're working on
+ int d_packetlen; // length of packet
+ int d_packetlen_cnt; // how many so far
+
+ protected:
+ gr_framer_sink_1(gr_msg_queue_sptr target_queue);
+
+ void enter_search();
+ void enter_have_sync();
+ void enter_have_header(int payload_len);
+
+ bool header_ok()
+ {
+ // confirm that two copies of header info are identical
+ return ((d_header >> 16) ^ (d_header & 0xffff)) == 0;
+ }
+
+ int header_payload_len()
+ {
+ // header consists of two 16-bit shorts in network byte order
+ int t = (d_header >> 16) & 0xffff;
+ return t;
+ }
+
+ public:
+ ~gr_framer_sink_1();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_FRAMER_SINK_1_H */
diff --git a/gnuradio-core/src/lib/general/gr_framer_sink_1.i b/gnuradio-core/src/lib/general/gr_framer_sink_1.i
new file mode 100644
index 0000000000..fbc556961e
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,framer_sink_1);
+
+gr_framer_sink_1_sptr
+gr_make_framer_sink_1(gr_msg_queue_sptr target_queue);
+
+class gr_framer_sink_1 : public gr_sync_block
+{
+ protected:
+ gr_framer_sink_1(gr_msg_queue_sptr target_queue);
+
+ public:
+ ~gr_framer_sink_1();
+};
diff --git a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.cc b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.cc
new file mode 100644
index 0000000000..271b8d33ab
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.cc
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_frequency_modulator_fc.h>
+#include <gr_io_signature.h>
+#include <gr_sincos.h>
+#include <math.h>
+
+
+gr_frequency_modulator_fc_sptr gr_make_frequency_modulator_fc (double sensitivity)
+{
+ return gr_frequency_modulator_fc_sptr (new gr_frequency_modulator_fc (sensitivity));
+}
+
+gr_frequency_modulator_fc::gr_frequency_modulator_fc (double sensitivity)
+ : gr_sync_block ("frequency_modulator_fc",
+ gr_make_io_signature (1, 1, sizeof (float)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex))),
+ d_sensitivity (sensitivity), d_phase (0)
+{
+}
+
+int
+gr_frequency_modulator_fc::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ for (int i = 0; i < noutput_items; i++){
+ d_phase = d_phase + d_sensitivity * in[i];
+ float oi, oq;
+ gr_sincosf (d_phase, &oq, &oi);
+ out[i] = gr_complex (oi, oq);
+ }
+
+ // Limit the phase accumulator to [-16*pi,16*pi]
+ // to avoid loss of precision in the addition above.
+
+ if (fabs (d_phase) > 16 * M_PI){
+ double ii = trunc (d_phase / (2 * M_PI));
+ d_phase = d_phase - (ii * 2 * M_PI);
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h
new file mode 100644
index 0000000000..6080adb9e3
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_FREQUENCY_MODULATOR_FC_H
+#define INCLUDED_GR_FREQUENCY_MODULATOR_FC_H
+
+#include <gr_sync_block.h>
+
+class gr_frequency_modulator_fc;
+typedef boost::shared_ptr<gr_frequency_modulator_fc> gr_frequency_modulator_fc_sptr;
+
+gr_frequency_modulator_fc_sptr gr_make_frequency_modulator_fc (double sensitivity);
+
+/*!
+ * \brief Frequency modulator block
+ * \ingroup block
+ *
+ * float input; complex baseband output
+ */
+class gr_frequency_modulator_fc : public gr_sync_block
+{
+ double d_sensitivity;
+ double d_phase;
+
+ friend gr_frequency_modulator_fc_sptr
+ gr_make_frequency_modulator_fc (double sensitivity);
+
+ gr_frequency_modulator_fc (double sensitivity);
+
+ public:
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_FREQUENCY_MODULATOR_FC_H */
diff --git a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.i b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.i
new file mode 100644
index 0000000000..04a8b5363a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,frequency_modulator_fc)
+
+gr_frequency_modulator_fc_sptr gr_make_frequency_modulator_fc (double sensitivity);
+
+class gr_frequency_modulator_fc : public gr_sync_block
+{
+ private:
+ gr_frequency_modulator_fc (double sensitivity);
+};
diff --git a/gnuradio-core/src/lib/general/gr_fxpt.cc b/gnuradio-core/src/lib/general/gr_fxpt.cc
new file mode 100644
index 0000000000..62ed8bd67a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fxpt.cc
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_fxpt.h>
+
+const float gr_fxpt::s_sine_table[1 << NBITS][2] = {
+#include "sine_table.h"
+};
+
+// gcc 4.x fix
+const float gr_fxpt::TWO_TO_THE_31;
+const float gr_fxpt::PI;
+
+#if 0
+/*
+ * Compute sine using table lookup with linear interpolation.
+ * Each table entry contains slope and intercept.
+ */
+float
+gr_fxpt::sin (gr_int32 x)
+{
+ gr_uint32 ux = x;
+ int index = ux >> (WORDBITS - NBITS);
+ return s_sine_table[index][0] * (ux >> 1) + s_sine_table[index][1];
+}
+
+float
+gr_fxpt::cos (gr_int32 x)
+{
+ gr_uint32 ux = x + 0x40000000;
+ int index = ux >> (WORDBITS - NBITS);
+ return s_sine_table[index][0] * (ux >> 1) + s_sine_table[index][1];
+}
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_fxpt.h b/gnuradio-core/src/lib/general/gr_fxpt.h
new file mode 100644
index 0000000000..fc8432d64b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fxpt.h
@@ -0,0 +1,82 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_FXPT_H
+#define INCLUDED_GR_FXPT_H
+
+#include <gr_types.h>
+
+/*!
+ * \brief fixed point sine and cosine and friends.
+ *
+ * fixed pt radians
+ * --------- --------
+ * -2**31 -pi
+ * 0 0
+ * 2**31-1 pi - epsilon
+ *
+ */
+class gr_fxpt
+{
+ static const int WORDBITS = 32;
+ static const int NBITS = 10;
+ static const float s_sine_table[1 << NBITS][2];
+ static const float PI = 3.14159265358979323846;
+ static const float TWO_TO_THE_31 = 2147483648.0;
+public:
+
+ static gr_int32
+ float_to_fixed (float x)
+ {
+ return (gr_int32) ((float) x * TWO_TO_THE_31 / PI);
+ }
+
+ static float
+ fixed_to_float (gr_int32 x)
+ {
+ return x * (PI / TWO_TO_THE_31);
+ }
+
+ /*!
+ * \brief Given a fixed point angle x, return float sine (x)
+ */
+ static float
+ sin (gr_int32 x)
+ {
+ gr_uint32 ux = x;
+ int index = ux >> (WORDBITS - NBITS);
+ return s_sine_table[index][0] * (ux >> 1) + s_sine_table[index][1];
+ }
+
+ /*
+ * \brief Given a fixed point angle x, return float cosine (x)
+ */
+ static float
+ cos (gr_int32 x)
+ {
+ gr_uint32 ux = x + 0x40000000;
+ int index = ux >> (WORDBITS - NBITS);
+ return s_sine_table[index][0] * (ux >> 1) + s_sine_table[index][1];
+ }
+
+};
+
+#endif /* INCLUDED_GR_FXPT_H */
diff --git a/gnuradio-core/src/lib/general/gr_fxpt_nco.h b/gnuradio-core/src/lib/general/gr_fxpt_nco.h
new file mode 100644
index 0000000000..c779bdfe53
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fxpt_nco.h
@@ -0,0 +1,151 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_FXPT_NCO_H
+#define INCLUDED_GR_FXPT_NCO_H
+
+#include <gr_fxpt.h>
+#include <gr_complex.h>
+
+/*!
+ * \brief Numerically Controlled Oscillator (NCO)
+ */
+class gr_fxpt_nco {
+ gr_int32 d_phase;
+ gr_int32 d_phase_inc;
+
+public:
+ gr_fxpt_nco () : d_phase (0), d_phase_inc (0) {}
+
+ ~gr_fxpt_nco () {}
+
+ // radians
+ void set_phase (float angle) {
+ d_phase = gr_fxpt::float_to_fixed (angle);
+ }
+
+ void adjust_phase (float delta_phase) {
+ d_phase += gr_fxpt::float_to_fixed (delta_phase);
+ }
+
+ // angle_rate is in radians / step
+ void set_freq (float angle_rate){
+ d_phase_inc = gr_fxpt::float_to_fixed (angle_rate);
+ }
+
+ // angle_rate is a delta in radians / step
+ void adjust_freq (float delta_angle_rate)
+ {
+ d_phase_inc += gr_fxpt::float_to_fixed (delta_angle_rate);
+ }
+
+ // increment current phase angle
+
+ void step ()
+ {
+ d_phase += d_phase_inc;
+ }
+
+ void step (int n)
+ {
+ d_phase += d_phase_inc * n;
+ }
+
+ // units are radians / step
+ float get_phase () const { return gr_fxpt::fixed_to_float (d_phase); }
+ float get_freq () const { return gr_fxpt::fixed_to_float (d_phase_inc); }
+
+ // compute sin and cos for current phase angle
+ void sincos (float *sinx, float *cosx) const
+ {
+ *sinx = gr_fxpt::sin (d_phase);
+ *cosx = gr_fxpt::cos (d_phase);
+ }
+
+ // compute cos and sin for a block of phase angles
+ void sincos (gr_complex *output, int noutput_items, double ampl=1.0)
+ {
+ for (int i = 0; i < noutput_items; i++){
+ output[i] = gr_complex(gr_fxpt::cos (d_phase) * ampl, gr_fxpt::sin (d_phase) * ampl);
+ step ();
+ }
+ }
+
+ // compute sin for a block of phase angles
+ void sin (float *output, int noutput_items, double ampl=1.0)
+ {
+ for (int i = 0; i < noutput_items; i++){
+ output[i] = (float)(gr_fxpt::sin (d_phase) * ampl);
+ step ();
+ }
+ }
+
+ // compute cos for a block of phase angles
+ void cos (float *output, int noutput_items, double ampl=1.0)
+ {
+ for (int i = 0; i < noutput_items; i++){
+ output[i] = (float)(gr_fxpt::cos (d_phase) * ampl);
+ step ();
+ }
+ }
+
+ // compute sin for a block of phase angles
+ void sin (short *output, int noutput_items, double ampl=1.0)
+ {
+ for (int i = 0; i < noutput_items; i++){
+ output[i] = (short)(gr_fxpt::sin (d_phase) * ampl);
+ step ();
+ }
+ }
+
+ // compute cos for a block of phase angles
+ void cos (short *output, int noutput_items, double ampl=1.0)
+ {
+ for (int i = 0; i < noutput_items; i++){
+ output[i] = (short)(gr_fxpt::cos (d_phase) * ampl);
+ step ();
+ }
+ }
+
+ // compute sin for a block of phase angles
+ void sin (int *output, int noutput_items, double ampl=1.0)
+ {
+ for (int i = 0; i < noutput_items; i++){
+ output[i] = (int)(gr_fxpt::sin (d_phase) * ampl);
+ step ();
+ }
+ }
+
+ // compute cos for a block of phase angles
+ void cos (int *output, int noutput_items, double ampl=1.0)
+ {
+ for (int i = 0; i < noutput_items; i++){
+ output[i] = (int)(gr_fxpt::cos (d_phase) * ampl);
+ step ();
+ }
+ }
+
+ // compute cos or sin for current phase angle
+ float cos () const { return gr_fxpt::cos (d_phase); }
+ float sin () const { return gr_fxpt::sin (d_phase); }
+};
+
+#endif /* INCLUDED_GR_FXPT_NCO_H */
diff --git a/gnuradio-core/src/lib/general/gr_fxpt_vco.h b/gnuradio-core/src/lib/general/gr_fxpt_vco.h
new file mode 100644
index 0000000000..c57a577b3b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fxpt_vco.h
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2004,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_FXPT_VCO_H
+#define INCLUDED_GR_FXPT_VCO_H
+
+#include <gr_fxpt.h>
+#include <gr_complex.h>
+
+/*!
+ * \brief Voltage Controlled Oscillator (VCO)
+ */
+class gr_fxpt_vco {
+ gr_int32 d_phase;
+
+public:
+ gr_fxpt_vco () : d_phase (0) {}
+
+ ~gr_fxpt_vco () {}
+
+ // radians
+ void set_phase (float angle) {
+ d_phase = gr_fxpt::float_to_fixed (angle);
+ }
+
+ void adjust_phase (float delta_phase) {
+ d_phase += gr_fxpt::float_to_fixed (delta_phase);
+ }
+
+ float get_phase () const { return gr_fxpt::fixed_to_float (d_phase); }
+
+ // compute sin and cos for current phase angle
+ void sincos (float *sinx, float *cosx) const
+ {
+ *sinx = gr_fxpt::sin (d_phase);
+ *cosx = gr_fxpt::cos (d_phase);
+ }
+
+ // compute a block at a time
+ void cos (float *output, const float *input, int noutput_items, float k, float ampl = 1.0)
+ {
+ for (int i = 0; i < noutput_items; i++){
+ output[i] = (float)(gr_fxpt::cos (d_phase) * ampl);
+ adjust_phase(input[i] * k);
+ }
+ }
+
+ // compute cos or sin for current phase angle
+ float cos () const { return gr_fxpt::cos (d_phase); }
+ float sin () const { return gr_fxpt::sin (d_phase); }
+};
+
+#endif /* INCLUDED_GR_FXPT_VCO_H */
diff --git a/gnuradio-core/src/lib/general/gr_head.cc b/gnuradio-core/src/lib/general/gr_head.cc
new file mode 100644
index 0000000000..7771ed515b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_head.cc
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_head.h>
+#include <gr_io_signature.h>
+
+gr_head::gr_head (size_t sizeof_stream_item, int nitems)
+ : gr_sync_block ("head",
+ gr_make_io_signature (1, 1, sizeof_stream_item),
+ gr_make_io_signature (1, 1, sizeof_stream_item)),
+ d_nitems (nitems), d_ncopied_items (0)
+{
+}
+
+gr_block_sptr
+gr_make_head (size_t sizeof_stream_item, int nitems)
+{
+ return gr_block_sptr (new gr_head (sizeof_stream_item, nitems));
+}
+
+int
+gr_head::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ if (d_ncopied_items >= d_nitems)
+ return -1; // Done!
+
+ unsigned n = std::min (d_nitems - d_ncopied_items, noutput_items);
+
+ if (n == 0)
+ return 0;
+
+ memcpy (output_items[0], input_items[0], n * input_signature()->sizeof_stream_item (0));
+ d_ncopied_items += n;
+
+ return n;
+}
diff --git a/gnuradio-core/src/lib/general/gr_head.h b/gnuradio-core/src/lib/general/gr_head.h
new file mode 100644
index 0000000000..125ee14b66
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_head.h
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_HEAD_H
+#define INCLUDED_GR_HEAD_H
+
+#include <gr_sync_block.h>
+#include <stddef.h> // size_t
+
+/*!
+ * \brief copies the first N items to the output then signals done
+ * \ingroup block
+ *
+ * Useful for building test cases
+ */
+
+class gr_head : public gr_sync_block
+{
+ friend gr_block_sptr gr_make_head (size_t sizeof_stream_item, int nitems);
+ gr_head (size_t sizeof_stream_item, int nitems);
+
+ int d_nitems;
+ int d_ncopied_items;
+
+ public:
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+gr_block_sptr
+gr_make_head (size_t sizeof_stream_item, int nitems);
+
+
+#endif /* INCLUDED_GR_HEAD_H */
diff --git a/gnuradio-core/src/lib/general/gr_head.i b/gnuradio-core/src/lib/general/gr_head.i
new file mode 100644
index 0000000000..0a34214dbf
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_head.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+%ignore gr_head;
+class gr_head : public gr_block {
+ friend gr_block_sptr gr_make_head (size_t sizeof_stream_item, int nitems);
+ gr_head (size_t sizeof_stream_item, int nitems);
+};
+
+%rename(head) gr_make_head;
+gr_block_sptr gr_make_head (size_t sizeof_stream_item, int nitems);
diff --git a/gnuradio-core/src/lib/general/gr_interleave.cc b/gnuradio-core/src/lib/general/gr_interleave.cc
new file mode 100644
index 0000000000..cae0cd9dc1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_interleave.cc
@@ -0,0 +1,77 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_interleave.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+
+gr_interleave_sptr
+gr_make_interleave (size_t itemsize)
+{
+ return gr_interleave_sptr (new gr_interleave (itemsize));
+}
+
+gr_interleave::gr_interleave (size_t itemsize)
+ : gr_sync_interpolator ("interleave",
+ gr_make_io_signature (1, gr_io_signature::IO_INFINITE, itemsize),
+ gr_make_io_signature (1, 1, itemsize),
+ 1),
+ d_itemsize (itemsize)
+{
+}
+
+gr_interleave::~gr_interleave ()
+{
+ // NOP
+}
+
+bool
+gr_interleave::check_topology (int ninputs, int noutputs)
+{
+ set_interpolation (ninputs);
+ return true;
+}
+
+int
+gr_interleave::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ size_t nchan = input_items.size ();
+ size_t itemsize = d_itemsize;
+ const char **in = (const char **) &input_items[0];
+ char *out = (char *) output_items[0];
+
+ for (int i = 0; i < noutput_items; i += nchan){
+ for (unsigned int n = 0; n < nchan; n++){
+ memcpy (out, in[n], itemsize);
+ out += itemsize;
+ in[n] += itemsize;
+ }
+ }
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_interleave.h b/gnuradio-core/src/lib/general/gr_interleave.h
new file mode 100644
index 0000000000..128ed7ce13
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_interleave.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_INTERLEAVE_H
+#define INCLUDED_GR_INTERLEAVE_H
+
+#include <gr_sync_interpolator.h>
+
+class gr_interleave;
+typedef boost::shared_ptr<gr_interleave> gr_interleave_sptr;
+
+gr_interleave_sptr gr_make_interleave (size_t itemsize);
+
+/*!
+ * \brief interleave N inputs to a single output
+ * \ingroup block
+ */
+class gr_interleave : public gr_sync_interpolator
+{
+ friend gr_interleave_sptr gr_make_interleave (size_t itemsize);
+
+ size_t d_itemsize;
+
+ gr_interleave (size_t itemsize);
+
+public:
+ ~gr_interleave ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ bool check_topology (int ninputs, int noutputs);
+
+};
+
+#endif /* INCLUDED_GR_INTERLEAVE_H */
diff --git a/gnuradio-core/src/lib/general/gr_interleave.i b/gnuradio-core/src/lib/general/gr_interleave.i
new file mode 100644
index 0000000000..f082531fc7
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,interleave)
+
+gr_interleave_sptr gr_make_interleave (size_t itemsize);
+
+class gr_interleave : public gr_sync_interpolator
+{
+ gr_interleave (size_t itemsize);
+};
diff --git a/gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.cc b/gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.cc
new file mode 100644
index 0000000000..c43e725438
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.cc
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_interleaved_short_to_complex.h>
+#include <gr_io_signature.h>
+#include <gri_interleaved_short_to_complex.h>
+
+gr_interleaved_short_to_complex_sptr
+gr_make_interleaved_short_to_complex ()
+{
+ return gr_interleaved_short_to_complex_sptr (new gr_interleaved_short_to_complex ());
+}
+
+gr_interleaved_short_to_complex::gr_interleaved_short_to_complex ()
+ : gr_sync_decimator ("gr_interleaved_short_to_complex",
+ gr_make_io_signature (1, 1, sizeof (short)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ 2)
+{
+}
+
+int
+gr_interleaved_short_to_complex::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const short *in = (const short *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ gri_interleaved_short_to_complex (in, out, 2 * noutput_items);
+
+ return noutput_items;
+}
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.h b/gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.h
new file mode 100644
index 0000000000..0eb1a32fa8
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.h
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_INTERLEAVED_SHORT_TO_COMPLEX_H
+#define INCLUDED_GR_INTERLEAVED_SHORT_TO_COMPLEX_H
+
+#include <gr_sync_decimator.h>
+
+class gr_interleaved_short_to_complex;
+typedef boost::shared_ptr<gr_interleaved_short_to_complex>
+ gr_interleaved_short_to_complex_sptr;
+
+gr_interleaved_short_to_complex_sptr
+gr_make_interleaved_short_to_complex ();
+
+/*!
+ * \brief Convert stream of interleaved shorts to a stream of complex
+ * \ingroup converter
+ */
+
+class gr_interleaved_short_to_complex : public gr_sync_decimator
+{
+ friend gr_interleaved_short_to_complex_sptr gr_make_interleaved_short_to_complex ();
+ gr_interleaved_short_to_complex ();
+
+ public:
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_INTERLEAVED_SHORT_TO_COMPLEX_H */
diff --git a/gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.i b/gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.i
new file mode 100644
index 0000000000..02d1ec0126
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,interleaved_short_to_complex)
+
+gr_interleaved_short_to_complex_sptr gr_make_interleaved_short_to_complex ();
+
+class gr_interleaved_short_to_complex : public gr_sync_decimator
+{
+ gr_interleaved_short_to_complex ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_keep_one_in_n.cc b/gnuradio-core/src/lib/general/gr_keep_one_in_n.cc
new file mode 100644
index 0000000000..e302070863
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_keep_one_in_n.cc
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_keep_one_in_n.h>
+#include <gr_io_signature.h>
+
+gr_keep_one_in_n_sptr
+gr_make_keep_one_in_n (size_t item_size, int n)
+{
+ return gr_keep_one_in_n_sptr (new gr_keep_one_in_n (item_size, n));
+}
+
+gr_keep_one_in_n::gr_keep_one_in_n (size_t item_size, int n)
+ : gr_block ("keep_one_in_n",
+ gr_make_io_signature (1, 1, item_size),
+ gr_make_io_signature (1, 1, item_size)),
+ d_n (n), d_count(n)
+{
+}
+
+void
+gr_keep_one_in_n::set_n(int n)
+{
+ if (n < 1)
+ n = 1;
+
+ d_n = n;
+ d_count = n;
+}
+
+int
+gr_keep_one_in_n::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const char *in = (const char *) input_items[0];
+ char *out = (char *) output_items[0];
+
+ size_t item_size = input_signature ()->sizeof_stream_item (0);
+ int ni = 0;
+ int no = 0;
+
+ while (ni < ninput_items[0] && no < noutput_items){
+ d_count--;
+ if (d_count <= 0){
+ memcpy (out, in, item_size); // copy 1 item
+ out += item_size;
+ no++;
+ d_count = d_n;
+ }
+ in += item_size;
+ ni++;
+ }
+
+ consume_each (ni);
+ return no;
+}
diff --git a/gnuradio-core/src/lib/general/gr_keep_one_in_n.h b/gnuradio-core/src/lib/general/gr_keep_one_in_n.h
new file mode 100644
index 0000000000..44a8474071
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_keep_one_in_n.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_KEEP_ONE_IN_N_H
+#define INCLUDED_GR_KEEP_ONE_IN_N_H
+
+#include <gr_sync_decimator.h>
+
+class gr_keep_one_in_n;
+typedef boost::shared_ptr<gr_keep_one_in_n> gr_keep_one_in_n_sptr;
+
+gr_keep_one_in_n_sptr
+gr_make_keep_one_in_n (size_t item_size, int n);
+
+
+/*!
+ * \brief decimate a stream, keeping one item out of every n.
+ * \ingroup block
+ */
+class gr_keep_one_in_n : public gr_block
+{
+ friend gr_keep_one_in_n_sptr
+ gr_make_keep_one_in_n (size_t item_size, int n);
+
+ int d_n;
+ int d_count;
+
+ protected:
+ gr_keep_one_in_n (size_t item_size, int n);
+
+ public:
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ void set_n(int n);
+
+};
+
+#endif /* INCLUDED_GR_KEEP_ONE_IN_N_H */
diff --git a/gnuradio-core/src/lib/general/gr_keep_one_in_n.i b/gnuradio-core/src/lib/general/gr_keep_one_in_n.i
new file mode 100644
index 0000000000..13ed9a3869
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,keep_one_in_n)
+
+gr_keep_one_in_n_sptr
+gr_make_keep_one_in_n (size_t itemsize, int n);
+
+class gr_keep_one_in_n : public gr_block
+{
+ protected:
+ gr_keep_one_in_n (size_t itemsize, int n);
+
+ public:
+ void set_n(int n);
+};
diff --git a/gnuradio-core/src/lib/general/gr_kludge_copy.cc b/gnuradio-core/src/lib/general/gr_kludge_copy.cc
new file mode 100644
index 0000000000..bf980d239f
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_kludge_copy.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+gr_kludge_copy_sptr
+gr_make_kludge_copy(size_t itemsize)
+{
+ return gr_kludge_copy_sptr(new gr_kludge_copy(itemsize));
+}
+
+gr_kludge_copy::gr_kludge_copy(size_t itemsize)
+ : gr_sync_block ("kludge_copy",
+ gr_make_io_signature (1, -1, sizeof (float)),
+ gr_make_io_signature (1, -1, sizeof (float))),
+ d_itemsize(itemsize)
+{
+}
+
+bool
+gr_kludge_copy::check_topology(int ninputs, int noutputs)
+{
+ return ninputs == noutputs;
+}
+
+int
+gr_kludge_copy::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float **in = (const float **) &input_items[0];
+ float **out = (float **) &output_items[0];
+
+ int ninputs = input_items.size();
+ for (int i = 0; i < ninputs; i++){
+ memcpy(out[i], in[i], noutput_items * d_itemsize);
+ }
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_kludge_copy.h b/gnuradio-core/src/lib/general/gr_kludge_copy.h
new file mode 100644
index 0000000000..d1cf54eecc
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_kludge_copy.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_KLUDGE_COPY_H
+#define INCLUDED_GR_KLUDGE_COPY_H
+
+#include <gr_sync_block.h>
+
+class gr_kludge_copy;
+typedef boost::shared_ptr<gr_kludge_copy> gr_kludge_copy_sptr;
+
+gr_kludge_copy_sptr gr_make_kludge_copy(size_t itemsize);
+
+/*!
+ * \brief output[i] = input[i]
+ * \ingroup block
+ *
+ * This is a short term kludge to work around a problem with the hierarchical block impl.
+ */
+class gr_kludge_copy : public gr_sync_block
+{
+ size_t d_itemsize;
+
+ friend gr_kludge_copy_sptr gr_make_kludge_copy(size_t itemsize);
+ gr_kludge_copy(size_t itemsize);
+
+ public:
+
+ bool check_topology(int ninputs, int noutputs);
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_kludge_copy.i b/gnuradio-core/src/lib/general/gr_kludge_copy.i
new file mode 100644
index 0000000000..828ec212f0
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,kludge_copy)
+
+gr_kludge_copy_sptr gr_make_kludge_copy(size_t itemsize);
+
+class gr_kludge_copy : public gr_sync_block
+{
+ private:
+ gr_kludge_copy(size_t itemsize);
+};
diff --git a/gnuradio-core/src/lib/general/gr_lfsr_32k_source_s.cc b/gnuradio-core/src/lib/general/gr_lfsr_32k_source_s.cc
new file mode 100644
index 0000000000..8a0b876862
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_lfsr_32k_source_s.cc
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_lfsr_32k_source_s.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+
+gr_lfsr_32k_source_s_sptr
+gr_make_lfsr_32k_source_s ()
+{
+ return gr_lfsr_32k_source_s_sptr (new gr_lfsr_32k_source_s ());
+}
+
+
+gr_lfsr_32k_source_s::gr_lfsr_32k_source_s ()
+ : gr_sync_block ("lfsr_32k_source_s",
+ gr_make_io_signature (0, 0, 0),
+ gr_make_io_signature (1, 1, sizeof (short))),
+ d_index (0)
+{
+ gri_lfsr_32k lfsr;
+
+ for (int i = 0; i < BUFSIZE; i++)
+ d_buffer[i] = lfsr.next_short ();
+}
+
+int
+gr_lfsr_32k_source_s::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ short *out = (short *) output_items[0];
+ short *buf = d_buffer;
+ int index = d_index;
+
+ for (int i = 0; i < noutput_items; i++){
+ out[i] = buf[index];
+ // index = (index + 1) & (BUFSIZE - 1);
+ index = index + 1;
+ if (index >= BUFSIZE)
+ index = 0;
+ }
+
+ d_index = index;
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_lfsr_32k_source_s.h b/gnuradio-core/src/lib/general/gr_lfsr_32k_source_s.h
new file mode 100644
index 0000000000..d3d72a9868
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_lfsr_32k_source_s.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_LFSR_32K_SOURCE_S_H
+#define INCLUDED_GR_LFSR_32K_SOURCE_S_H
+
+#include <gr_sync_block.h>
+#include <gri_lfsr_32k.h>
+
+class gr_lfsr_32k_source_s;
+typedef boost::shared_ptr<gr_lfsr_32k_source_s> gr_lfsr_32k_source_s_sptr;
+
+gr_lfsr_32k_source_s_sptr gr_make_lfsr_32k_source_s ();
+
+/*!
+ * \brief LFSR pseudo-random source with period of 2^15 bits (2^11 shorts)
+ * \ingroup source
+ *
+ * This source is typically used along with gr_check_lfsr_32k_s to test
+ * the USRP using its digital loopback mode.
+ */
+class gr_lfsr_32k_source_s : public gr_sync_block
+{
+ friend gr_lfsr_32k_source_s_sptr gr_make_lfsr_32k_source_s ();
+
+
+ static const int BUFSIZE = 2048 - 1; // ensure pattern isn't packet aligned
+ int d_index;
+ short d_buffer[BUFSIZE];
+
+ gr_lfsr_32k_source_s ();
+
+ public:
+
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_lfsr_32k_source_s.i b/gnuradio-core/src/lib/general/gr_lfsr_32k_source_s.i
new file mode 100644
index 0000000000..60b6267961
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,lfsr_32k_source_s);
+
+gr_lfsr_32k_source_s_sptr gr_make_lfsr_32k_source_s ();
+
+class gr_lfsr_32k_source_s : public gr_sync_block
+{
+ private:
+ gr_lfsr_32k_source_s ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_lms_dfe_cc.cc b/gnuradio-core/src/lib/general/gr_lms_dfe_cc.cc
new file mode 100644
index 0000000000..874ad84f9f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_lms_dfe_cc.cc
@@ -0,0 +1,148 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_lms_dfe_cc.h>
+#include <gr_io_signature.h>
+#include <gr_misc.h>
+#include <iostream>
+
+gr_complex
+gr_lms_dfe_cc::slicer_0deg (gr_complex sample)
+{
+ gr_complex out;
+ if(fabs(real(sample))>fabs(imag(sample))) {
+ if(real(sample) > 0)
+ out = gr_complex(1,0);
+ else
+ out = gr_complex(-1,0);
+ }
+ else {
+ if(imag(sample) > 0)
+ out = gr_complex(0,1);
+ else
+ out = gr_complex(0,-1);
+ }
+ return out;
+}
+
+gr_complex
+gr_lms_dfe_cc::slicer_45deg (gr_complex sample)
+{
+ gr_complex out;
+ if(real(sample) > 0)
+ out = gr_complex(1,0);
+ else
+ out = gr_complex(-1,0);
+ if(imag(sample) > 0)
+ out += gr_complex(0,1);
+ else
+ out += gr_complex(0,-1);
+ return out;
+}
+
+gr_lms_dfe_cc_sptr
+gr_make_lms_dfe_cc (float lambda_ff, float lambda_fb,
+ unsigned int num_fftaps, unsigned int num_fbtaps)
+{
+ return gr_lms_dfe_cc_sptr (new gr_lms_dfe_cc (lambda_ff, lambda_fb,
+ num_fftaps, num_fbtaps));
+}
+
+gr_lms_dfe_cc::gr_lms_dfe_cc (float lambda_ff, float lambda_fb ,
+ unsigned int num_fftaps, unsigned int num_fbtaps)
+ : gr_sync_block ("lms_dfe_cc",
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex))),
+ d_lambda_ff (lambda_ff), d_lambda_fb (lambda_fb),
+ d_ff_delayline(gr_rounduppow2(num_fftaps)),
+ d_fb_delayline(gr_rounduppow2(num_fbtaps)),
+ d_ff_taps(num_fftaps),d_fb_taps(num_fbtaps),
+ d_ff_index(0), d_fb_index(0)
+{
+ gr_zero_vector(d_ff_taps);
+ d_ff_taps [d_ff_taps.size()/2] = 1;
+
+ gr_zero_vector(d_fb_taps);
+ gr_zero_vector(d_ff_delayline);
+ gr_zero_vector(d_fb_delayline);
+}
+
+int
+gr_lms_dfe_cc::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *iptr = (const gr_complex *) input_items[0];
+ gr_complex *optr = (gr_complex *) output_items[0];
+
+ gr_complex acc, decision, error;
+ unsigned int i;
+
+ unsigned int ff_mask = d_ff_delayline.size() - 1; // size is power of 2
+ unsigned int fb_mask = d_fb_delayline.size() - 1;
+
+ int size = noutput_items;
+ while (size-- > 0){
+ acc = 0;
+ d_ff_delayline[d_ff_index] = *iptr++;
+
+ // Compute output
+ for (i=0; i < d_ff_taps.size(); i++)
+ acc += conj(d_ff_delayline[(i+d_ff_index) & ff_mask]) * d_ff_taps[i];
+
+ for (i=0; i < d_fb_taps.size(); i++)
+ acc -= conj(d_fb_delayline[(i+d_fb_index) & fb_mask]) * d_fb_taps[i];
+
+ decision = slicer_45deg(acc);
+ error = decision - acc;
+
+ // Update taps
+ for (i=0; i < d_ff_taps.size(); i++)
+ d_ff_taps[i] += d_lambda_ff * conj(error) * d_ff_delayline[(i+d_ff_index) & ff_mask];
+
+ for (i=0; i < d_fb_taps.size(); i++)
+ d_fb_taps[i] -= d_lambda_fb * conj(error) * d_fb_delayline[(i+d_fb_index) & fb_mask];
+
+ d_fb_index = (d_fb_index - 1) & fb_mask; // Decrement index
+ d_ff_index = (d_ff_index - 1) & ff_mask; // Decrement index
+
+ d_fb_delayline[d_fb_index] = decision; // Save decision in feedback
+
+ *optr++ = acc; // Output decision
+ }
+
+ if (0){
+ std::cout << "FF Taps\t";
+ for(i=0;i<d_ff_taps.size();i++)
+ std::cout << d_ff_taps[i] << "\t";
+ std::cout << std::endl << "FB Taps\t";
+ for(i=0;i<d_fb_taps.size();i++)
+ std::cout << d_fb_taps[i] << "\t";
+ std::cout << std::endl;
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_lms_dfe_cc.h b/gnuradio-core/src/lib/general/gr_lms_dfe_cc.h
new file mode 100644
index 0000000000..034c26d86e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_lms_dfe_cc.h
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_LMS_DFE_CC_H
+#define INCLUDED_GR_LMS_DFE_CC_H
+
+#include <gr_sync_block.h>
+
+class gr_lms_dfe_cc;
+typedef boost::shared_ptr<gr_lms_dfe_cc> gr_lms_dfe_cc_sptr;
+
+gr_lms_dfe_cc_sptr gr_make_lms_dfe_cc (float lambda_ff, float lambda_fb,
+ unsigned int num_fftaps, unsigned int num_fbtaps);
+
+/*!
+ * \brief Least-Mean-Square Decision Feedback Equalizer (complex in/out)
+ * \ingroup block
+ */
+class gr_lms_dfe_cc : public gr_sync_block
+{
+ friend gr_lms_dfe_cc_sptr gr_make_lms_dfe_cc (float lambda_ff, float lambda_fb,
+ unsigned int num_fftaps, unsigned int num_fbtaps);
+
+ float d_lambda_ff;
+ float d_lambda_fb;
+ std::vector<gr_complex> d_ff_delayline;
+ std::vector<gr_complex> d_fb_delayline;
+ std::vector<gr_complex> d_ff_taps;
+ std::vector<gr_complex> d_fb_taps;
+ unsigned int d_ff_index;
+ unsigned int d_fb_index;
+
+ gr_lms_dfe_cc (float lambda_ff, float lambda_fb,
+ unsigned int num_fftaps, unsigned int num_fbtaps);
+ gr_complex slicer_0deg(gr_complex baud);
+ gr_complex slicer_45deg(gr_complex baud);
+
+ public:
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_lms_dfe_cc.i b/gnuradio-core/src/lib/general/gr_lms_dfe_cc.i
new file mode 100644
index 0000000000..4ea4a6ae1f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_lms_dfe_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+GR_SWIG_BLOCK_MAGIC(gr,lms_dfe_cc)
+
+gr_lms_dfe_cc_sptr gr_make_lms_dfe_cc (float lambda_ff, float lambda_fb,
+ unsigned int num_fftaps, unsigned int num_fbtaps);
+
+class gr_lms_dfe_cc : public gr_sync_block
+{
+ private:
+ gr_lms_dfe_cc (float lambda_ff, float lambda_fb,
+ unsigned int num_fftaps, unsigned int num_fbtaps);
+ gr_complex slicer_0deg(gr_complex baud);
+ gr_complex slicer_45deg(gr_complex baud);
+ gr_complex conjg(gr_complex val);
+};
diff --git a/gnuradio-core/src/lib/general/gr_lms_dfe_ff.cc b/gnuradio-core/src/lib/general/gr_lms_dfe_ff.cc
new file mode 100644
index 0000000000..017c90a215
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_lms_dfe_ff.cc
@@ -0,0 +1,122 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_lms_dfe_ff.h>
+#include <gr_io_signature.h>
+#include <gr_misc.h>
+#include <iostream>
+
+float
+slice(float val)
+{
+ if (val>0)
+ return 1;
+ else
+ return -1;
+}
+
+gr_lms_dfe_ff_sptr
+gr_make_lms_dfe_ff (float lambda_ff, float lambda_fb,
+ unsigned int num_fftaps, unsigned int num_fbtaps)
+{
+ return gr_lms_dfe_ff_sptr (new gr_lms_dfe_ff (lambda_ff,lambda_fb,num_fftaps,num_fbtaps));
+}
+
+gr_lms_dfe_ff::gr_lms_dfe_ff (float lambda_ff, float lambda_fb ,
+ unsigned int num_fftaps, unsigned int num_fbtaps)
+ : gr_sync_block ("lms_dfe_ff",
+ gr_make_io_signature (1, 1, sizeof (float)),
+ gr_make_io_signature (1, 1, sizeof (float))),
+ d_lambda_ff (lambda_ff), d_lambda_fb (lambda_fb),
+ d_ff_delayline(gr_rounduppow2(num_fftaps)),
+ d_fb_delayline(gr_rounduppow2(num_fbtaps)),
+ d_ff_taps(num_fftaps), d_fb_taps(num_fbtaps),
+ d_ff_index(0), d_fb_index(0)
+{
+ gr_zero_vector(d_ff_taps);
+ d_ff_taps [d_ff_taps.size()/2] = 1;
+
+ gr_zero_vector(d_fb_taps);
+ gr_zero_vector(d_ff_delayline);
+ gr_zero_vector(d_fb_delayline);
+}
+
+int
+gr_lms_dfe_ff::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *iptr = (const float *) input_items[0];
+ float *optr = (float *) output_items[0];
+
+ float acc, decision, error;
+ unsigned int i;
+
+ unsigned int ff_mask = d_ff_delayline.size() - 1; // size is power of 2
+ unsigned int fb_mask = d_fb_delayline.size() - 1;
+
+ int size = noutput_items;
+ while(size-- > 0) {
+ acc = 0;
+ d_ff_delayline[d_ff_index] = *iptr++;
+
+ // Compute output
+ for (i=0; i < d_ff_taps.size(); i++)
+ acc += d_ff_delayline[(i+d_ff_index) & ff_mask] * d_ff_taps[i];
+
+ for (i=0; i < d_fb_taps.size(); i++)
+ acc -= d_fb_delayline[(i+d_fb_index) & fb_mask] * d_fb_taps[i];
+
+ decision = slice(acc);
+ error = decision - acc;
+
+ // Update taps
+ for (i=0; i < d_ff_taps.size(); i++)
+ d_ff_taps[i] += d_lambda_ff * error * d_ff_delayline[(i+d_ff_index) & ff_mask];
+
+ for (i=0; i < d_fb_taps.size(); i++)
+ d_fb_taps[i] -= d_lambda_fb * error * d_fb_delayline[(i+d_fb_index) & fb_mask];
+
+ d_fb_index = (d_fb_index - 1) & fb_mask; // Decrement index
+ d_ff_index = (d_ff_index - 1) & ff_mask; // Decrement index
+
+ d_fb_delayline[d_fb_index] = decision; // Save decision in feedback
+
+ *optr++ = acc; // Output decision
+ }
+
+ if (0){
+ std::cout << "FF Taps\t";
+ for(i=0;i<d_ff_taps.size();i++)
+ std::cout << d_ff_taps[i] << "\t";
+ std::cout << std::endl << "FB Taps\t";
+ for(i=0;i<d_fb_taps.size();i++)
+ std::cout << d_fb_taps[i] << "\t";
+ std::cout << std::endl;
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_lms_dfe_ff.h b/gnuradio-core/src/lib/general/gr_lms_dfe_ff.h
new file mode 100644
index 0000000000..338b0a1447
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_lms_dfe_ff.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_LMS_DFE_FF_H
+#define INCLUDED_GR_LMS_DFE_FF_H
+
+#include <gr_sync_block.h>
+
+class gr_lms_dfe_ff;
+typedef boost::shared_ptr<gr_lms_dfe_ff> gr_lms_dfe_ff_sptr;
+
+gr_lms_dfe_ff_sptr gr_make_lms_dfe_ff (float lambda_ff, float lambda_fb,
+ unsigned int num_fftaps, unsigned int num_fbtaps);
+
+/*!
+ * \brief Least-Mean-Square Decision Feedback Equalizer (float in/out)
+ * \ingroup block
+ */
+class gr_lms_dfe_ff : public gr_sync_block
+{
+ friend gr_lms_dfe_ff_sptr gr_make_lms_dfe_ff (float lambda_ff, float lambda_fb,
+ unsigned int num_fftaps, unsigned int num_fbtaps);
+
+ float d_lambda_ff;
+ float d_lambda_fb;
+ std::vector<float> d_ff_delayline;
+ std::vector<float> d_fb_delayline;
+ std::vector<float> d_ff_taps;
+ std::vector<float> d_fb_taps;
+ unsigned int d_ff_index;
+ unsigned int d_fb_index;
+
+ gr_lms_dfe_ff (float lambda_ff, float lambda_fb,
+ unsigned int num_fftaps, unsigned int num_fbtaps);
+
+ public:
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_lms_dfe_ff.i b/gnuradio-core/src/lib/general/gr_lms_dfe_ff.i
new file mode 100644
index 0000000000..6b9e439d08
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_lms_dfe_ff.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+GR_SWIG_BLOCK_MAGIC(gr,lms_dfe_ff)
+
+gr_lms_dfe_ff_sptr gr_make_lms_dfe_ff (float lambda_ff, float lambda_fb,
+ unsigned int num_fftaps, unsigned int num_fbtaps);
+
+class gr_lms_dfe_ff : public gr_sync_block
+{
+ private:
+ gr_lms_dfe_ff (float lambda_ff, float lambda_fb,
+ unsigned int num_fftaps, unsigned int num_fbtaps);
+};
diff --git a/gnuradio-core/src/lib/general/gr_log2_const.h b/gnuradio-core/src/lib/general/gr_log2_const.h
new file mode 100644
index 0000000000..fe255045cc
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_log2_const.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+/*
+ * a bit of template hackery...
+ */
+#ifndef INCLUDED_GR_LOG2_CONST_H
+#define INCLUDED_GR_LOG2_CONST_H
+
+#include <assert.h>
+
+template<unsigned int k> static inline int gr_log2_const() { assert(0); }
+
+template<> static inline int gr_log2_const<1>() { return 0; }
+template<> static inline int gr_log2_const<2>() { return 1; }
+template<> static inline int gr_log2_const<4>() { return 2; }
+template<> static inline int gr_log2_const<8>() { return 3; }
+template<> static inline int gr_log2_const<16>() { return 4; }
+template<> static inline int gr_log2_const<32>() { return 5; }
+template<> static inline int gr_log2_const<64>() { return 6; }
+template<> static inline int gr_log2_const<128>() { return 7; }
+template<> static inline int gr_log2_const<256>() { return 8; }
+template<> static inline int gr_log2_const<512>() { return 9; }
+template<> static inline int gr_log2_const<1024>(){ return 10; }
+
+#endif /* INCLUDED_GR_LOG2_CONST_H */
diff --git a/gnuradio-core/src/lib/general/gr_map_bb.cc b/gnuradio-core/src/lib/general/gr_map_bb.cc
new file mode 100644
index 0000000000..891ff02ce3
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_map_bb.cc
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_map_bb.h>
+#include <gr_io_signature.h>
+
+gr_map_bb_sptr
+gr_make_map_bb (const std::vector<int> &map)
+{
+ return gr_map_bb_sptr (new gr_map_bb (map));
+}
+
+gr_map_bb::gr_map_bb (const std::vector<int> &map)
+ : gr_sync_block ("map_bb",
+ gr_make_io_signature (1, 1, sizeof (unsigned char)),
+ gr_make_io_signature (1, 1, sizeof (unsigned char)))
+{
+ for (int i = 0; i < 0x100; i++)
+ d_map[i] = i;
+
+ unsigned int size = std::max((size_t) 0x100, map.size());
+ for (unsigned int i = 0; i < size; i++)
+ d_map[i] = map[i];
+}
+
+int
+gr_map_bb::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+
+ for (int i = 0; i < noutput_items; i++)
+ out[i] = d_map[in[i]];
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_map_bb.h b/gnuradio-core/src/lib/general/gr_map_bb.h
new file mode 100644
index 0000000000..f5f7fa8dd0
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_map_bb.h
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_MAP_BB_H
+#define INCLUDED_GR_MAP_BB_H
+
+#include <gr_sync_block.h>
+
+class gr_map_bb;
+typedef boost::shared_ptr<gr_map_bb> gr_map_bb_sptr;
+
+gr_map_bb_sptr gr_make_map_bb(const std::vector<int> &map);
+
+/*!
+ * \brief output[i] = map[input[i]]
+ * \ingroup block
+ */
+
+class gr_map_bb : public gr_sync_block
+{
+ friend gr_map_bb_sptr gr_make_map_bb(const std::vector<int> &map);
+
+ unsigned char d_map[0x100];
+
+ gr_map_bb(const std::vector<int> &map);
+
+public:
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_MAP_BB_H */
diff --git a/gnuradio-core/src/lib/general/gr_map_bb.i b/gnuradio-core/src/lib/general/gr_map_bb.i
new file mode 100644
index 0000000000..a4282a3ebe
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,map_bb);
+
+gr_map_bb_sptr gr_make_map_bb (const std::vector<int> &map);
+
+class gr_map_bb : public gr_sync_block
+{
+ private:
+ gr_map_bb (const std::vector<int> &map);
+};
+
diff --git a/gnuradio-core/src/lib/general/gr_math.cc b/gnuradio-core/src/lib/general/gr_math.cc
new file mode 100644
index 0000000000..e2e7249e2b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_math.cc
@@ -0,0 +1,102 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_math.h>
+#include <math.h>
+
+/*
+ * Greatest Common Divisor, using Euclid's algorithm.
+ * [There are faster algorithms. See Knuth 4.5.2 if you care]
+ */
+
+long
+gr_gcd (long m, long n)
+{
+ if (m < 0)
+ m = -m;
+
+ if (n < 0)
+ n = -n;
+
+ while (n != 0){
+ long t = m % n;
+ m = n;
+ n = t;
+ }
+
+ return m;
+}
+
+
+/*
+ * These really need some configure hacking to figure out the right answer.
+ * As a stop gap, try for a macro, and if not that, then try std::
+ */
+
+// returns a non-zero value if value is "not-a-number" (NaN), and 0 otherwise
+
+#if defined(isnan) || !defined(CXX_HAS_STD_ISNAN)
+
+int
+gr_isnan (double value)
+{
+ return isnan (value);
+}
+
+#else
+
+int
+gr_isnan (double value)
+{
+ return std::isnan (value);
+}
+
+#endif
+
+// returns a non-zero value if the value of x has its sign bit set.
+//
+// This is not the same as `x < 0.0', because IEEE 754 floating point
+// allows zero to be signed. The comparison `-0.0 < 0.0' is false, but
+// `gr_signbit (-0.0)' will return a nonzero value.
+
+#ifdef signbit
+
+int
+gr_signbit (double x)
+{
+ return signbit (x);
+}
+
+#else
+
+int
+gr_signbit (double x)
+{
+ return std::signbit (x);
+}
+
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_math.h b/gnuradio-core/src/lib/general/gr_math.h
new file mode 100644
index 0000000000..5ce8fb7827
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_math.h
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * mathematical odds and ends.
+ */
+
+#ifndef _GR_MATH_H_
+#define _GR_MATH_H_
+
+long gr_gcd (long m, long n);
+
+// returns a non-zero value if value is "not-a-number" (NaN), and 0 otherwise
+int gr_isnan (double value);
+
+// returns a non-zero value if the value of x has its sign bit set.
+//
+// This is not the same as `x < 0.0', because IEEE 754 floating point
+// allows zero to be signed. The comparison `-0.0 < 0.0' is false, but
+// `gr_signbit (-0.0)' will return a nonzero value.
+
+int gr_signbit (double x);
+
+/*!
+ * \brief Fast arc tangent using table lookup and linear interpolation
+ *
+ * \param y component of input vector
+ * \param x component of input vector
+ * \returns float angle angle of vector (x, y) in radians
+ *
+ * This function calculates the angle of the vector (x,y) based on a
+ * table lookup and linear interpolation. The table uses a 256 point
+ * table covering -45 to +45 degrees and uses symetry to determine the
+ * final angle value in the range of -180 to 180 degrees. Note that
+ * this function uses the small angle approximation for values close
+ * to zero. This routine calculates the arc tangent with an average
+ * error of +/- 0.045 degrees.
+ */
+float gr_fast_atan2f(float y, float x);
+
+#endif /* _GR_MATH_H_ */
diff --git a/gnuradio-core/src/lib/general/gr_misc.cc b/gnuradio-core/src/lib/general/gr_misc.cc
new file mode 100644
index 0000000000..d15202273a
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_misc.h>
+
+unsigned int
+gr_rounduppow2(unsigned int n)
+{
+ int i;
+ for (i=0;((n-1)>>i) != 0;i++)
+ ;
+ return 1<<i;
+}
+
+// ----------------------------------------------------------------
+
+void
+gr_zero_vector(std::vector<float> &v)
+{
+ for(unsigned int i=0; i < v.size(); i++)
+ v[i] = 0;
+}
+
+void
+gr_zero_vector(std::vector<double> &v)
+{
+ for(unsigned int i=0; i < v.size(); i++)
+ v[i] = 0;
+}
+
+void
+gr_zero_vector(std::vector<int> &v)
+{
+ for(unsigned int i=0; i < v.size(); i++)
+ v[i] = 0;
+}
+
+void
+gr_zero_vector(std::vector<gr_complex> &v)
+{
+ for(unsigned int i=0; i < v.size(); i++)
+ v[i] = 0;
+}
diff --git a/gnuradio-core/src/lib/general/gr_misc.h b/gnuradio-core/src/lib/general/gr_misc.h
new file mode 100644
index 0000000000..177df96485
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_misc.h
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_MISC_H
+#define INCLUDED_GR_MISC_H
+
+#include <gr_types.h>
+
+unsigned int
+gr_rounduppow2(unsigned int n);
+
+// FIXME should be template
+void gr_zero_vector(std::vector<float> &v);
+void gr_zero_vector(std::vector<double> &v);
+void gr_zero_vector(std::vector<int> &v);
+void gr_zero_vector(std::vector<gr_complex> &v);
+
+
+#endif /* INCLUDED_GR_MISC_H */
diff --git a/gnuradio-core/src/lib/general/gr_multiply_XX.cc.t b/gnuradio-core/src/lib/general/gr_multiply_XX.cc.t
new file mode 100644
index 0000000000..a9c43224f5
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_XX.cc.t
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ ()
+{
+ return @SPTR_NAME@ (new @NAME@ ());
+}
+
+@NAME@::@NAME@ ()
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (1, -1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@)))
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0];
+
+ int ninputs = input_items.size ();
+
+ for (int i = 0; i < noutput_items; i++){
+ @I_TYPE@ acc = ((@I_TYPE@ *) input_items[0])[i];
+ for (int j = 1; j < ninputs; j++)
+ acc *= ((@I_TYPE@ *) input_items[j])[i];
+
+ *optr++ = (@O_TYPE@) acc;
+ }
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_multiply_XX.h.t b/gnuradio-core/src/lib/general/gr_multiply_XX.h.t
new file mode 100644
index 0000000000..cfa416f1fa
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_XX.h.t
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+/*!
+ * \brief output = prod (input_0, input_1, ...)
+ * \ingroup block
+ *
+ * Multiply across all input streams.
+ */
+class @NAME@ : public gr_sync_block
+{
+ friend @SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+ @NAME@ ();
+
+ public:
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_multiply_XX.i.t b/gnuradio-core/src/lib/general/gr_multiply_XX.i.t
new file mode 100644
index 0000000000..8479aad683
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+ @NAME@ ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_XX.cc.t b/gnuradio-core/src/lib/general/gr_multiply_const_XX.cc.t
new file mode 100644
index 0000000000..b312b9c013
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_const_XX.cc.t
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (@O_TYPE@ k)
+{
+ return @SPTR_NAME@ (new @NAME@ (k));
+}
+
+@NAME@::@NAME@ (@O_TYPE@ k)
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@))),
+ d_k (k)
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ @I_TYPE@ *iptr = (@I_TYPE@ *) input_items[0];
+ @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0];
+
+ int size = noutput_items;
+
+ while (size >= 8){
+ *optr++ = *iptr++ * d_k;
+ *optr++ = *iptr++ * d_k;
+ *optr++ = *iptr++ * d_k;
+ *optr++ = *iptr++ * d_k;
+ *optr++ = *iptr++ * d_k;
+ *optr++ = *iptr++ * d_k;
+ *optr++ = *iptr++ * d_k;
+ *optr++ = *iptr++ * d_k;
+ size -= 8;
+ }
+
+ while (size-- > 0)
+ *optr++ = *iptr++ * d_k;
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_XX.h.t b/gnuradio-core/src/lib/general/gr_multiply_const_XX.h.t
new file mode 100644
index 0000000000..6e771e0b02
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_const_XX.h.t
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (@O_TYPE@ k);
+
+/*!
+ * \brief output = input * constant
+ * \ingroup block
+ */
+class @NAME@ : public gr_sync_block
+{
+ friend @SPTR_NAME@ gr_make_@BASE_NAME@ (@O_TYPE@ k);
+
+ @O_TYPE@ d_k; // the constant
+ @NAME@ (@O_TYPE@ k);
+
+ public:
+ @O_TYPE@ k () const { return d_k; }
+ void set_k (@O_TYPE@ k) { d_k = k; }
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_XX.i.t b/gnuradio-core/src/lib/general/gr_multiply_const_XX.i.t
new file mode 100644
index 0000000000..c2c814b524
--- /dev/null
+++ b/gnuradio-core/src/lib/general/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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (@TYPE@ k);
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+ @NAME@ (@TYPE@ k);
+
+ public:
+ @TYPE@ k () const { return d_k; }
+ void set_k (@TYPE@ k) { d_k = k; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_vXX.cc.t b/gnuradio-core/src/lib/general/gr_multiply_const_vXX.cc.t
new file mode 100755
index 0000000000..9b723a3e8c
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_const_vXX.cc.t
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k)
+{
+ return @SPTR_NAME@ (new @NAME@ (k));
+}
+
+@NAME@::@NAME@ (const std::vector<@I_TYPE@> k)
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof(@I_TYPE@)*k.size()),
+ gr_make_io_signature (1, 1, sizeof(@O_TYPE@)*k.size()))
+{
+ d_k = k;
+}
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ @I_TYPE@ *iptr = (@O_TYPE@ *)input_items[0];
+ @O_TYPE@ *optr = (@O_TYPE@ *)output_items[0];
+
+ int nitems_per_block = output_signature()->sizeof_stream_item(0)/sizeof(@I_TYPE@);
+
+ for (int i = 0; i < noutput_items; i++)
+ for (int j = 0; j < nitems_per_block; j++)
+ *optr++ = *iptr++ * d_k[j];
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_vXX.h.t b/gnuradio-core/src/lib/general/gr_multiply_const_vXX.h.t
new file mode 100755
index 0000000000..dba875c3f2
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_const_vXX.h.t
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k);
+
+/*!
+ * \brief output vector = input vector * constant vector (element-wise)
+ * \ingroup block
+ */
+class @NAME@ : public gr_sync_block
+{
+ friend @SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k);
+
+ std::vector<@I_TYPE@> d_k; // the constant
+ @NAME@ (const std::vector<@I_TYPE@> k);
+
+ public:
+ const std::vector<@I_TYPE@> k () const { return d_k; }
+ void set_k (const std::vector<@I_TYPE@> k) { d_k = k; }
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_vXX.i.t b/gnuradio-core/src/lib/general/gr_multiply_const_vXX.i.t
new file mode 100755
index 0000000000..38c399438a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_const_vXX.i.t
@@ -0,0 +1,37 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k);
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+ @NAME@ (const std::vector<@I_TYPE@> k);
+
+ public:
+ std::vector<@I_TYPE@> k () const { return d_k; }
+ void set_k (const std::vector<@I_TYPE@> k) { d_k = k; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_multiply_vXX.cc.t b/gnuradio-core/src/lib/general/gr_multiply_vXX.cc.t
new file mode 100755
index 0000000000..cc242ddadd
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_vXX.cc.t
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (size_t nitems_per_block)
+{
+ return @SPTR_NAME@ (new @NAME@ (nitems_per_block));
+}
+
+@NAME@::@NAME@ (size_t nitems_per_block)
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (1, -1, sizeof (@I_TYPE@)*nitems_per_block),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@)*nitems_per_block))
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0];
+
+ int ninputs = input_items.size ();
+ int nitems_per_block = output_signature()->sizeof_stream_item(0)/sizeof(@I_TYPE@);
+
+ for (int i = 0; i < noutput_items; i++){
+ for (int j = 0; j < nitems_per_block; j++){
+ @I_TYPE@ acc = ((@I_TYPE@ *) input_items[0])[i*nitems_per_block+j];
+ for (int k = 1; k < ninputs; k++)
+ acc *= ((@I_TYPE@ *) input_items[k])[i*nitems_per_block+j];
+
+ *optr++ = (@O_TYPE@) acc;
+ }
+ }
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_multiply_vXX.h.t b/gnuradio-core/src/lib/general/gr_multiply_vXX.h.t
new file mode 100755
index 0000000000..c6388d931f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_vXX.h.t
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (size_t nitems_per_block);
+
+/*!
+ * \brief output = prod (input_0, input_1, ...)
+ * \ingroup block
+ *
+ * Element-wise multiply across all input vectors.
+ */
+class @NAME@ : public gr_sync_block
+{
+ friend @SPTR_NAME@ gr_make_@BASE_NAME@ (size_t nitems_per_block);
+
+ @NAME@ (size_t nitems_per_block);
+
+ public:
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_multiply_vXX.i.t b/gnuradio-core/src/lib/general/gr_multiply_vXX.i.t
new file mode 100755
index 0000000000..0810961039
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_vXX.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (size_t nitems_per_block);
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+ @NAME@ (size_t nitems_per_block);
+};
diff --git a/gnuradio-core/src/lib/general/gr_mute_XX.cc.t b/gnuradio-core/src/lib/general/gr_mute_XX.cc.t
new file mode 100644
index 0000000000..740821e5ea
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_mute_XX.cc.t
@@ -0,0 +1,79 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (bool mute)
+{
+ return @SPTR_NAME@ (new @NAME@ (mute));
+}
+
+@NAME@::@NAME@ (bool mute)
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@))),
+ d_mute (mute)
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ @I_TYPE@ *iptr = (@I_TYPE@ *) input_items[0];
+ @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0];
+
+ int size = noutput_items;
+
+ if (d_mute){
+ memset (optr, 0, noutput_items * sizeof(@O_TYPE@));
+ }
+ else {
+ while (size >= 8){
+ *optr++ = *iptr++;
+ *optr++ = *iptr++;
+ *optr++ = *iptr++;
+ *optr++ = *iptr++;
+ *optr++ = *iptr++;
+ *optr++ = *iptr++;
+ *optr++ = *iptr++;
+ *optr++ = *iptr++;
+ size -= 8;
+ }
+
+ while (size-- > 0)
+ *optr++ = *iptr++;
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_mute_XX.h.t b/gnuradio-core/src/lib/general/gr_mute_XX.h.t
new file mode 100644
index 0000000000..88915322e5
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_mute_XX.h.t
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (bool mute=false);
+
+/*!
+ * \brief output = input or zero if muted.
+ * \ingroup block
+ */
+class @NAME@ : public gr_sync_block
+{
+ friend @SPTR_NAME@ gr_make_@BASE_NAME@ (bool mute);
+
+ bool d_mute;
+ @NAME@ (bool mute);
+
+ public:
+ bool mute () const { return d_mute; }
+ void set_mute (bool mute) { d_mute = mute; }
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_mute_XX.i.t b/gnuradio-core/src/lib/general/gr_mute_XX.i.t
new file mode 100644
index 0000000000..413e529812
--- /dev/null
+++ b/gnuradio-core/src/lib/general/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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@(bool mute=false);
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+ @NAME@ (bool mute);
+
+ public:
+ bool mute () const { return d_mute; }
+ void set_mute (bool mute) { d_mute = mute; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_nco.h b/gnuradio-core/src/lib/general/gr_nco.h
new file mode 100644
index 0000000000..2cf41fd775
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_nco.h
@@ -0,0 +1,197 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _GR_NCO_H_
+#define _GR_NCO_H_
+
+
+#include <vector>
+#include <gr_sincos.h>
+#include <cmath>
+#include <gr_complex.h>
+
+/*!
+ * \brief base class template for Numerically Controlled Oscillator (NCO)
+ */
+
+
+//FIXME Eventually generalize this to fixed point
+
+template<class o_type, class i_type>
+class gr_nco {
+public:
+ gr_nco () : phase (0), phase_inc(0) {}
+
+ virtual ~gr_nco () {}
+
+ // radians
+ void set_phase (double angle) {
+ phase = angle;
+ }
+
+ void adjust_phase (double delta_phase) {
+ phase += delta_phase;
+ }
+
+
+ // angle_rate is in radians / step
+ void set_freq (double angle_rate){
+ phase_inc = angle_rate;
+ }
+
+ // angle_rate is a delta in radians / step
+ void adjust_freq (double delta_angle_rate)
+ {
+ phase_inc += delta_angle_rate;
+ }
+
+ // increment current phase angle
+
+ void step ()
+ {
+ phase += phase_inc;
+ if (fabs (phase) > M_PI){
+
+ while (phase > M_PI)
+ phase -= 2*M_PI;
+
+ while (phase < -M_PI)
+ phase += 2*M_PI;
+ }
+ }
+
+ void step (int n)
+ {
+ phase += phase_inc * n;
+ if (fabs (phase) > M_PI){
+
+ while (phase > M_PI)
+ phase -= 2*M_PI;
+
+ while (phase < -M_PI)
+ phase += 2*M_PI;
+ }
+ }
+
+ // units are radians / step
+ double get_phase () const { return phase; }
+ double get_freq () const { return phase_inc; }
+
+ // compute sin and cos for current phase angle
+ void sincos (float *sinx, float *cosx) const;
+
+ // compute cos or sin for current phase angle
+ float cos () const { return std::cos (phase); }
+ float sin () const { return std::sin (phase); }
+
+ // compute a block at a time
+ void sin (float *output, int noutput_items, double ampl = 1.0);
+ void cos (float *output, int noutput_items, double ampl = 1.0);
+ void sincos (gr_complex *output, int noutput_items, double ampl = 1.0);
+ void sin (short *output, int noutput_items, double ampl = 1.0);
+ void cos (short *output, int noutput_items, double ampl = 1.0);
+ void sin (int *output, int noutput_items, double ampl = 1.0);
+ void cos (int *output, int noutput_items, double ampl = 1.0);
+
+protected:
+ double phase;
+ double phase_inc;
+};
+
+template<class o_type, class i_type>
+void
+gr_nco<o_type,i_type>::sincos (float *sinx, float *cosx) const
+{
+ gr_sincosf (phase, sinx, cosx);
+}
+
+template<class o_type, class i_type>
+void
+gr_nco<o_type,i_type>::sin (float *output, int noutput_items, double ampl)
+{
+ for (int i = 0; i < noutput_items; i++){
+ output[i] = (float)(sin () * ampl);
+ step ();
+ }
+}
+
+template<class o_type, class i_type>
+void
+gr_nco<o_type,i_type>::cos (float *output, int noutput_items, double ampl)
+{
+ for (int i = 0; i < noutput_items; i++){
+ output[i] = (float)(cos () * ampl);
+ step ();
+ }
+}
+
+template<class o_type, class i_type>
+void
+gr_nco<o_type,i_type>::sin (short *output, int noutput_items, double ampl)
+{
+ for (int i = 0; i < noutput_items; i++){
+ output[i] = (short)(sin() * ampl);
+ step ();
+ }
+}
+
+template<class o_type, class i_type>
+void
+gr_nco<o_type,i_type>::cos (short *output, int noutput_items, double ampl)
+{
+ for (int i = 0; i < noutput_items; i++){
+ output[i] = (short)(cos () * ampl);
+ step ();
+ }
+}
+
+template<class o_type, class i_type>
+void
+gr_nco<o_type,i_type>::sin (int *output, int noutput_items, double ampl)
+{
+ for (int i = 0; i < noutput_items; i++){
+ output[i] = (int)(sin () * ampl);
+ step ();
+ }
+}
+
+template<class o_type, class i_type>
+void
+gr_nco<o_type,i_type>::cos (int *output, int noutput_items, double ampl)
+{
+ for (int i = 0; i < noutput_items; i++){
+ output[i] = (int)(cos () * ampl);
+ step ();
+ }
+}
+
+template<class o_type, class i_type>
+void
+gr_nco<o_type,i_type>::sincos (gr_complex *output, int noutput_items, double ampl)
+{
+ for (int i = 0; i < noutput_items; i++){
+ float cosx, sinx;
+ sincos (&sinx, &cosx);
+ output[i] = gr_complex(cosx * ampl, sinx * ampl);
+ step ();
+ }
+}
+#endif /* _NCO_H_ */
diff --git a/gnuradio-core/src/lib/general/gr_nlog10_ff.cc b/gnuradio-core/src/lib/general/gr_nlog10_ff.cc
new file mode 100644
index 0000000000..71e8279abc
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_nlog10_ff.cc
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_nlog10_ff.h>
+#include <gr_io_signature.h>
+#include <algorithm>
+
+gr_nlog10_ff_sptr
+gr_make_nlog10_ff (float n, unsigned vlen, float k)
+{
+ return gr_nlog10_ff_sptr(new gr_nlog10_ff(n, vlen, k));
+}
+
+gr_nlog10_ff::gr_nlog10_ff(float n, unsigned vlen, float k)
+ : gr_sync_block("nlog10_ff",
+ gr_make_io_signature(1, 1, sizeof(float) * vlen),
+ gr_make_io_signature(1, 1, sizeof(float) * vlen)),
+ d_vlen(vlen), d_n(n), d_k(k)
+{
+}
+
+gr_nlog10_ff::~gr_nlog10_ff()
+{
+}
+
+int
+gr_nlog10_ff::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+ float *out = (float *) output_items[0];
+ int noi = noutput_items * d_vlen;
+ float n = d_n;
+ float k = d_k;
+
+ for (int i = 0; i < noi; i++)
+ out[i] = n * log10(std::max(in[i], (float) 1e-18)) + k;
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_nlog10_ff.h b/gnuradio-core/src/lib/general/gr_nlog10_ff.h
new file mode 100644
index 0000000000..04a6f80d0c
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_nlog10_ff.h
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_NLOG10_FF_H
+#define INCLUDED_GR_NLOG10_FF_H
+
+#include <gr_sync_block.h>
+
+class gr_nlog10_ff;
+typedef boost::shared_ptr<gr_nlog10_ff> gr_nlog10_ff_sptr;
+
+gr_nlog10_ff_sptr gr_make_nlog10_ff (float n=1.0, unsigned vlen=1, float k=0);
+
+/*!
+ * \brief output = n*log10(input) + k
+ * \ingroup block
+ */
+class gr_nlog10_ff : public gr_sync_block
+{
+ friend gr_nlog10_ff_sptr gr_make_nlog10_ff (float n, unsigned vlen, float k);
+
+ unsigned int d_vlen;
+ float d_n;
+ float d_k;
+
+ gr_nlog10_ff (float n, unsigned vlen, float k);
+
+public:
+ ~gr_nlog10_ff();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_NLOG10_FF_H */
diff --git a/gnuradio-core/src/lib/general/gr_nlog10_ff.i b/gnuradio-core/src/lib/general/gr_nlog10_ff.i
new file mode 100644
index 0000000000..3dbd12d833
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,nlog10_ff);
+
+gr_nlog10_ff_sptr gr_make_nlog10_ff (float n=1.0, unsigned vlen=1, float k=0);
+
+class gr_nlog10_ff : public gr_sync_block
+{
+ gr_nlog10_ff (float n, unsigned vlen, float k);
+
+public:
+ ~gr_nlog10_ff();
+};
diff --git a/gnuradio-core/src/lib/general/gr_noise_source_X.cc.t b/gnuradio-core/src/lib/general/gr_noise_source_X.cc.t
new file mode 100644
index 0000000000..401bed1903
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_noise_source_X.cc.t
@@ -0,0 +1,99 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (gr_noise_type_t type, float ampl, long seed)
+{
+ return @NAME@_sptr (new @NAME@ (type, ampl, seed));
+}
+
+
+@NAME@::@NAME@ (gr_noise_type_t type, float ampl, long seed)
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (0, 0, 0),
+ gr_make_io_signature (1, 1, sizeof (@TYPE@))),
+ d_type (type),
+ d_ampl (ampl),
+ d_rng (seed)
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ @TYPE@ *out = (@TYPE@ *) output_items[0];
+
+ switch (d_type){
+#if @IS_COMPLEX@ // complex?
+
+ case GR_UNIFORM:
+ for (int i = 0; i < noutput_items; i++)
+ out[i] = gr_complex (d_ampl * ((d_rng.ran1 () * 2.0) - 1.0),
+ d_ampl * ((d_rng.ran1 () * 2.0) - 1.0));
+ break;
+
+ case GR_GAUSSIAN:
+ for (int i = 0; i < noutput_items; i++)
+ out[i] = d_ampl * d_rng.rayleigh_complex ();
+ break;
+
+#else // nope...
+
+ case GR_UNIFORM:
+ for (int i = 0; i < noutput_items; i++)
+ out[i] = (@TYPE@)(d_ampl * ((d_rng.ran1 () * 2.0) - 1.0));
+ break;
+
+ case GR_GAUSSIAN:
+ for (int i = 0; i < noutput_items; i++)
+ out[i] = (@TYPE@)(d_ampl * d_rng.gasdev ());
+ break;
+
+ case GR_LAPLACIAN:
+ for (int i = 0; i < noutput_items; i++)
+ out[i] = (@TYPE@)(d_ampl * d_rng.laplacian ());
+ break;
+
+ case GR_IMPULSE: // FIXME changeable impulse settings
+ for (int i = 0; i < noutput_items; i++)
+ out[i] = (@TYPE@)(d_ampl * d_rng.impulse (9));
+ break;
+#endif
+
+ default:
+ throw std::runtime_error ("invalid type");
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_noise_source_X.h.t b/gnuradio-core/src/lib/general/gr_noise_source_X.h.t
new file mode 100644
index 0000000000..bc016affe1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_noise_source_X.h.t
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+#include <gr_noise_type.h>
+#include <gr_random.h>
+
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @NAME@_sptr;
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (gr_noise_type_t type, float ampl, long seed = 3021);
+
+/*!
+ * \brief random number source
+ * \ingroup source
+ */
+class @NAME@ : public gr_sync_block {
+ friend @NAME@_sptr
+ gr_make_@BASE_NAME@ (gr_noise_type_t type, float ampl, long seed);
+
+ gr_noise_type_t d_type;
+ float d_ampl;
+ gr_random d_rng;
+
+ @NAME@ (gr_noise_type_t type, float ampl, long seed = 3021);
+
+ public:
+ void set_type (gr_noise_type_t type) { d_type = type; }
+ void set_amplitude (float ampl) { d_ampl = ampl; }
+
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_noise_source_X.i.t b/gnuradio-core/src/lib/general/gr_noise_source_X.i.t
new file mode 100644
index 0000000000..0a3ad96a72
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_noise_source_X.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (gr_noise_type_t type, float ampl, long seed = 3021);
+
+class @NAME@ : public gr_block {
+ private:
+ @NAME@ (gr_noise_type_t type, float ampl, long seed = 3021);
+
+ public:
+ void set_type (gr_noise_type_t type) { d_type = type; }
+ void set_amplitude (float ampl) { d_ampl = ampl; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_noise_type.h b/gnuradio-core/src/lib/general/gr_noise_type.h
new file mode 100644
index 0000000000..886d5f446f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_NOISE_TYPE_H
+#define INCLUDED_GR_NOISE_TYPE_H
+
+typedef enum {
+ GR_UNIFORM = 200, GR_GAUSSIAN, GR_LAPLACIAN, GR_IMPULSE
+} gr_noise_type_t;
+
+#endif /* INCLUDED_GR_NOISE_TYPE_H */
diff --git a/gnuradio-core/src/lib/general/gr_nop.cc b/gnuradio-core/src/lib/general/gr_nop.cc
new file mode 100644
index 0000000000..0a3f4f330b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_nop.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_nop.h>
+#include <gr_io_signature.h>
+
+gr_nop::gr_nop (size_t sizeof_stream_item)
+ : gr_block ("nop",
+ gr_make_io_signature (0, -1, sizeof_stream_item),
+ gr_make_io_signature (0, -1, sizeof_stream_item))
+{
+}
+
+gr_block_sptr
+gr_make_nop (size_t sizeof_stream_item)
+{
+ return gr_block_sptr (new gr_nop (sizeof_stream_item));
+}
+
+int
+gr_nop::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ // eat any input that's available
+ for (unsigned i = 0; i < ninput_items.size (); i++)
+ consume (i, ninput_items[i]);
+
+ return noutput_items;
+}
+
+
diff --git a/gnuradio-core/src/lib/general/gr_nop.h b/gnuradio-core/src/lib/general/gr_nop.h
new file mode 100644
index 0000000000..faf938625d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_nop.h
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_NOP_H
+#define INCLUDED_GR_NOP_H
+
+#include <gr_block.h>
+#include <stddef.h> // size_t
+
+/*!
+ * \brief Does nothing. Used for testing only.
+ * \ingroup block
+ */
+class gr_nop : public gr_block
+{
+ friend gr_block_sptr gr_make_nop (size_t sizeof_stream_item);
+
+ gr_nop (size_t sizeof_stream_item);
+
+ public:
+ virtual int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+gr_block_sptr
+gr_make_nop (size_t sizeof_stream_item);
+
+#endif /* INCLUDED_GR_NOP_H */
diff --git a/gnuradio-core/src/lib/general/gr_nop.i b/gnuradio-core/src/lib/general/gr_nop.i
new file mode 100644
index 0000000000..556ad57304
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_nop.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+%ignore gr_nop;
+class gr_nop : public gr_block {
+ friend gr_block_sptr gr_make_nop (size_t sizeof_stream_item);
+ gr_nop (size_t sizeof_stream_item);
+};
+
+%rename(nop) gr_make_nop;
+gr_block_sptr gr_make_nop (size_t sizeof_stream_item);
diff --git a/gnuradio-core/src/lib/general/gr_null_sink.cc b/gnuradio-core/src/lib/general/gr_null_sink.cc
new file mode 100644
index 0000000000..7e9c7a790b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_null_sink.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_null_sink.h>
+#include <gr_io_signature.h>
+
+gr_null_sink::gr_null_sink (size_t sizeof_stream_item)
+ : gr_sync_block ("null_sink",
+ gr_make_io_signature (1, 1, sizeof_stream_item),
+ gr_make_io_signature (0, 0, 0))
+{
+}
+
+gr_block_sptr
+gr_make_null_sink (size_t sizeof_stream_item)
+{
+ return gr_block_sptr (new gr_null_sink (sizeof_stream_item));
+}
+
+int
+gr_null_sink::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_null_sink.h b/gnuradio-core/src/lib/general/gr_null_sink.h
new file mode 100644
index 0000000000..55b61aacc4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_null_sink.h
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_NULL_SINK_H
+#define INCLUDED_GR_NULL_SINK_H
+
+#include <gr_sync_block.h>
+#include <stddef.h> // size_t
+
+/*!
+ * \brief Bit bucket
+ * \ingroup sink
+ */
+
+class gr_null_sink : public gr_sync_block
+{
+ friend gr_block_sptr gr_make_null_sink (size_t sizeof_stream_item);
+
+ gr_null_sink (size_t sizeof_stream_item);
+
+ public:
+
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+};
+
+gr_block_sptr
+gr_make_null_sink (size_t sizeof_stream_item);
+
+#endif /* INCLUDED_GR_NULL_SINK_H */
diff --git a/gnuradio-core/src/lib/general/gr_null_sink.i b/gnuradio-core/src/lib/general/gr_null_sink.i
new file mode 100644
index 0000000000..145be901ff
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_null_sink.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+%ignore gr_null_sink;
+class gr_null_sink : public gr_sync_block {
+ friend gr_block_sptr gr_make_null_sink (size_t sizeof_stream_item);
+ gr_null_sink (size_t sizeof_stream_item);
+};
+
+%rename(null_sink) gr_make_null_sink;
+gr_block_sptr gr_make_null_sink (size_t sizeof_stream_item);
diff --git a/gnuradio-core/src/lib/general/gr_null_source.cc b/gnuradio-core/src/lib/general/gr_null_source.cc
new file mode 100644
index 0000000000..65923cf764
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_null_source.cc
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_null_source.h>
+#include <gr_io_signature.h>
+
+gr_null_source::gr_null_source (size_t sizeof_stream_item)
+ : gr_sync_block ("null_source",
+ gr_make_io_signature (0, 0, 0),
+ gr_make_io_signature (1, 1, sizeof_stream_item))
+{
+}
+
+gr_block_sptr
+gr_make_null_source (size_t sizeof_stream_item)
+{
+ return gr_block_sptr (new gr_null_source (sizeof_stream_item));
+}
+
+int
+gr_null_source::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ void *optr = (void *) output_items[0];
+ memset (optr, 0, noutput_items * output_signature()->sizeof_stream_item (0));
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_null_source.h b/gnuradio-core/src/lib/general/gr_null_source.h
new file mode 100644
index 0000000000..9fc43a0708
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_null_source.h
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_NULL_SOURCE_H
+#define INCLUDED_GR_NULL_SOURCE_H
+
+#include <gr_sync_block.h>
+
+/*!
+ * \brief A source of zeros.
+ * \ingroup source
+ */
+
+class gr_null_source : public gr_sync_block
+{
+ friend gr_block_sptr gr_make_null_source (size_t sizeof_stream_item);
+
+ gr_null_source (size_t sizeof_stream_item);
+
+ public:
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+};
+
+gr_block_sptr
+gr_make_null_source (size_t sizeof_stream_item);
+
+#endif /* INCLUDED_GR_NULL_SOURCE_H */
diff --git a/gnuradio-core/src/lib/general/gr_null_source.i b/gnuradio-core/src/lib/general/gr_null_source.i
new file mode 100644
index 0000000000..8a88f359c7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_null_source.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+%ignore gr_null_source;
+class gr_null_source : public gr_sync_block {
+ friend gr_block_sptr gr_make_null_source (size_t sizeof_stream_item);
+ gr_null_source (size_t sizeof_stream_item);
+};
+
+%rename(null_source) gr_make_null_source;
+gr_block_sptr gr_make_null_source (size_t sizeof_stream_item);
diff --git a/gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.cc b/gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.cc
new file mode 100644
index 0000000000..7f470af9a0
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.cc
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pa_2x2_phase_combiner.h>
+#include <gr_io_signature.h>
+
+gr_pa_2x2_phase_combiner_sptr
+gr_make_pa_2x2_phase_combiner()
+{
+ return gr_pa_2x2_phase_combiner_sptr(new gr_pa_2x2_phase_combiner());
+}
+
+gr_pa_2x2_phase_combiner::gr_pa_2x2_phase_combiner ()
+ : gr_sync_block ("pa_2x2_phase_combiner",
+ gr_make_io_signature (1, 1, NM * sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, sizeof (float)))
+{
+ set_theta(0);
+}
+
+void
+gr_pa_2x2_phase_combiner::set_theta(float theta)
+{
+ d_theta = theta;
+ gr_complex j = gr_complex(0,1);
+ d_phase[0] = exp(j * (float) (M_PI * (sin(theta) + cos(theta))));
+ d_phase[1] = exp(j * (float) (M_PI * cos(theta)));
+ d_phase[2] = exp(j * (float) (M_PI * sin(theta)));
+ d_phase[3] = exp(j * (float) 0.0);
+}
+
+int
+gr_pa_2x2_phase_combiner::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *in = (const gr_complex *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ for (int i = 0; i < noutput_items; i++){
+ gr_complex acc = 0;
+ acc += in[0] * d_phase[0];
+ acc += in[1] * d_phase[1];
+ acc += in[2] * d_phase[2];
+ acc += in[3] * d_phase[3];
+ out[i] = acc;
+ in += 4;
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.h b/gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.h
new file mode 100644
index 0000000000..e8634968bd
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_PA_2X2_PHASE_COMBINER_H
+#define INCLUDED_GR_PA_2X2_PHASE_COMBINER_H
+
+#include <gr_sync_block.h>
+
+class gr_pa_2x2_phase_combiner;
+typedef boost::shared_ptr<gr_pa_2x2_phase_combiner> gr_pa_2x2_phase_combiner_sptr;
+
+gr_pa_2x2_phase_combiner_sptr gr_make_pa_2x2_phase_combiner ();
+
+/*!
+ * \brief pa_2x2 phase combiner
+ * \ingroup block
+ *
+ * Anntenas are arranged like this:
+ *
+ * 2 3
+ * 0 1
+ *
+ * dx and dy are lambda/2.
+ */
+class gr_pa_2x2_phase_combiner : public gr_sync_block
+{
+ static const int NM = 4;
+
+ float d_theta;
+ gr_complex d_phase[NM];
+
+ gr_pa_2x2_phase_combiner ();
+ friend gr_pa_2x2_phase_combiner_sptr gr_make_pa_2x2_phase_combiner();
+
+ public:
+ float theta() const { return d_theta; }
+ void set_theta(float theta);
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_PA_2X2_PHASE_COMBINER_H */
diff --git a/gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.i b/gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.i
new file mode 100644
index 0000000000..a19413afd5
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pa_2x2_phase_combiner)
+
+gr_pa_2x2_phase_combiner_sptr gr_make_pa_2x2_phase_combiner();
+
+class gr_pa_2x2_phase_combiner : public gr_sync_block
+{
+ gr_pa_2x2_phase_combiner();
+
+ public:
+ float theta() const;
+ void set_theta(float theta);
+};
diff --git a/gnuradio-core/src/lib/general/gr_packed_to_unpacked_XX.cc.t b/gnuradio-core/src/lib/general/gr_packed_to_unpacked_XX.cc.t
new file mode 100644
index 0000000000..f585c4a6af
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_packed_to_unpacked_XX.cc.t
@@ -0,0 +1,133 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <gr_log2_const.h>
+
+static const unsigned int BITS_PER_TYPE = sizeof(@I_TYPE@) * 8;
+static const unsigned int LOG2_L_TYPE = gr_log2_const<sizeof(@I_TYPE@) * 8>();
+
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness)
+{
+ return @SPTR_NAME@
+ (new @NAME@ (bits_per_chunk,endianness));
+}
+
+@NAME@::@NAME@ (unsigned int bits_per_chunk,
+ gr_endianness_t endianness)
+ : gr_block ("@BASE_NAME@",
+ gr_make_io_signature (1, -1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, -1, sizeof (@O_TYPE@))),
+ d_bits_per_chunk(bits_per_chunk),d_endianness(endianness),d_index(0)
+{
+ assert (bits_per_chunk <= BITS_PER_TYPE);
+ assert (bits_per_chunk > 0);
+
+ set_relative_rate ((1.0 * BITS_PER_TYPE) / bits_per_chunk);
+}
+
+void
+@NAME@::forecast(int noutput_items, gr_vector_int &ninput_items_required)
+{
+
+ int input_required = (int) ceil((d_index + noutput_items * d_bits_per_chunk) / (1.0 * BITS_PER_TYPE));
+ unsigned ninputs = ninput_items_required.size();
+ for (unsigned int i = 0; i < ninputs; i++) {
+ ninput_items_required[i] = input_required;
+ //printf("Forecast wants %d needs %d\n",noutput_items,ninput_items_required[i]);
+ }
+}
+
+unsigned int
+get_bit_le (const @I_TYPE@ *in_vector,unsigned int bit_addr)
+{
+ @I_TYPE@ x = in_vector[bit_addr>>LOG2_L_TYPE];
+ return (x>>(bit_addr&(BITS_PER_TYPE-1)))&1;
+}
+
+unsigned int
+get_bit_be (const @I_TYPE@ *in_vector,unsigned int bit_addr)
+{
+ @I_TYPE@ x = in_vector[bit_addr>>LOG2_L_TYPE];
+ return (x>>((BITS_PER_TYPE-1)-(bit_addr&(BITS_PER_TYPE-1))))&1;
+}
+
+int
+@NAME@::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ assert (input_items.size() == output_items.size());
+ int nstreams = input_items.size();
+
+ for (int m=0; m < nstreams; m++){
+ const @I_TYPE@ *in = (@I_TYPE@ *) input_items[m];
+ @O_TYPE@ *out = (@O_TYPE@ *) output_items[m];
+
+ // per stream processing
+
+ switch (d_endianness){
+
+ case GR_MSB_FIRST:
+ for (int i = 0; i < noutput_items; i++){
+ //printf("here msb %d\n",i);
+ @O_TYPE@ x = 0;
+ for(unsigned int j=0; j<d_bits_per_chunk; j++, d_index++)
+ x = (x<<1) | get_bit_be(in, d_index);
+ out[i] = x;
+ }
+ break;
+
+ case GR_LSB_FIRST:
+ for (int i = 0; i < noutput_items; i++){
+ //printf("here lsb %d\n",i);
+ @O_TYPE@ x = 0;
+ for(unsigned int j=0; j<d_bits_per_chunk; j++, d_index++)
+ x = (x<<1) | get_bit_le(in, d_index);
+ out[i] = x;
+ }
+ break;
+
+ default:
+ assert(0);
+ }
+
+ //printf("almost got to end\n");
+ assert(ninput_items[m] >= (int) ((d_index+(BITS_PER_TYPE-1))>>LOG2_L_TYPE));
+ }
+
+ consume_each (d_index >> LOG2_L_TYPE);
+ d_index = d_index & (BITS_PER_TYPE-1);
+ //printf("got to end\n");
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_packed_to_unpacked_XX.h.t b/gnuradio-core/src/lib/general/gr_packed_to_unpacked_XX.h.t
new file mode 100644
index 0000000000..1c9d2a0d6c
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_packed_to_unpacked_XX.h.t
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_block.h>
+#include <gr_endianness.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness);
+
+/*!
+ * \brief Convert a stream of packed bytes or shorts to stream of unpacked bytes or shorts.
+ * \ingroup block
+ *
+ * input: stream of @I_TYPE@; output: stream of @O_TYPE@
+ *
+ * This is the inverse of gr_unpacked_to_packed_XX.
+ *
+ * The bits in the bytes or shorts input stream are grouped into chunks of
+ * \p bits_per_chunk bits and each resulting chunk is written right-
+ * justified to the output stream of bytes or shorts.
+ * All b or 16 bits of the each input bytes or short are processed.
+ * The right thing is done if bits_per_chunk is not a power of two.
+ *
+ * The combination of gr_packed_to_unpacked_XX_ followed by
+ * gr_chunks_to_symbols_Xf or gr_chunks_to_symbols_Xc handles the
+ * general case of mapping from a stream of bytes or shorts into
+ * arbitrary float or complex symbols.
+ *
+ * \sa gr_packed_to_unpacked_bb, gr_unpacked_to_packed_bb,
+ * \sa gr_packed_to_unpacked_ss, gr_unpacked_to_packed_ss,
+ * \sa gr_chunks_to_symbols_bf, gr_chunks_to_symbols_bc.
+ * \sa gr_chunks_to_symbols_sf, gr_chunks_to_symbols_sc.
+ */
+
+class @NAME@ : public gr_block
+{
+ friend @SPTR_NAME@
+ gr_make_@BASE_NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness);
+
+ @NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness);
+
+ unsigned int d_bits_per_chunk;
+ gr_endianness_t d_endianness;
+ unsigned int d_index;
+
+ public:
+ void forecast(int noutput_items, gr_vector_int &ninput_items_required);
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ bool check_topology(int ninputs, int noutputs) { return ninputs == noutputs; }
+
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_packed_to_unpacked_XX.i.t b/gnuradio-core/src/lib/general/gr_packed_to_unpacked_XX.i.t
new file mode 100644
index 0000000000..9517a8ac24
--- /dev/null
+++ b/gnuradio-core/src/lib/general/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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness);
+
+class @NAME@ : public gr_block
+{
+ @NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness);
+};
diff --git a/gnuradio-core/src/lib/general/gr_packet_sink.cc b/gnuradio-core/src/lib/general/gr_packet_sink.cc
new file mode 100644
index 0000000000..f88758b9b0
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_packet_sink.cc
@@ -0,0 +1,206 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_packet_sink.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+#include <gr_count_bits.h>
+
+#define VERBOSE 0
+
+static const int DEFAULT_THRESHOLD = 12; // detect access code with up to DEFAULT_THRESHOLD bits wrong
+
+inline void
+gr_packet_sink::enter_search()
+{
+ if (VERBOSE)
+ fprintf(stderr, "@ enter_search\n");
+
+ d_state = STATE_SYNC_SEARCH;
+ d_shift_reg = 0;
+}
+
+inline void
+gr_packet_sink::enter_have_sync()
+{
+ if (VERBOSE)
+ fprintf(stderr, "@ enter_have_sync\n");
+
+ d_state = STATE_HAVE_SYNC;
+ d_header = 0;
+ d_headerbitlen_cnt = 0;
+}
+
+inline void
+gr_packet_sink::enter_have_header(int payload_len)
+{
+ if (VERBOSE)
+ fprintf(stderr, "@ enter_have_header (payload_len = %d)\n", payload_len);
+
+ d_state = STATE_HAVE_HEADER;
+ d_packetlen = payload_len;
+ d_packetlen_cnt = 0;
+ d_packet_byte = 0;
+ d_packet_byte_index = 0;
+}
+
+gr_packet_sink_sptr
+gr_make_packet_sink (const std::vector<unsigned char>& sync_vector,
+ gr_msg_queue_sptr target_queue, int threshold)
+{
+ return gr_packet_sink_sptr (new gr_packet_sink (sync_vector, target_queue, threshold));
+}
+
+
+gr_packet_sink::gr_packet_sink (const std::vector<unsigned char>& sync_vector,
+ gr_msg_queue_sptr target_queue, int threshold)
+ : gr_sync_block ("packet_sink",
+ gr_make_io_signature (1, 1, sizeof(float)),
+ gr_make_io_signature (0, 0, 0)),
+ d_target_queue(target_queue), d_threshold(threshold == -1 ? DEFAULT_THRESHOLD : threshold)
+{
+ d_sync_vector = 0;
+ for(int i=0;i<8;i++){
+ d_sync_vector <<= 8;
+ d_sync_vector |= sync_vector[i];
+ }
+
+ enter_search();
+}
+
+gr_packet_sink::~gr_packet_sink ()
+{
+}
+
+int
+gr_packet_sink::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ float *inbuf = (float *) input_items[0];
+ int count=0;
+
+ if (VERBOSE)
+ fprintf(stderr,">>> Entering state machine\n"),fflush(stderr);
+
+ while (count<noutput_items) {
+ switch(d_state) {
+
+ case STATE_SYNC_SEARCH: // Look for sync vector
+ if (VERBOSE)
+ fprintf(stderr,"SYNC Search, noutput=%d\n",noutput_items),fflush(stderr);
+
+ while (count < noutput_items) {
+ if(slice(inbuf[count++]))
+ d_shift_reg = (d_shift_reg << 1) | 1;
+ else
+ d_shift_reg = d_shift_reg << 1;
+
+ // Compute popcnt of putative sync vector
+ if(gr_count_bits64 (d_shift_reg ^ d_sync_vector) <= d_threshold) {
+ // Found it, set up for header decode
+ enter_have_sync();
+ break;
+ }
+ }
+ break;
+
+ case STATE_HAVE_SYNC:
+ if (VERBOSE)
+ fprintf(stderr,"Header Search bitcnt=%d, header=0x%08x\n", d_headerbitlen_cnt, d_header),
+ fflush(stderr);
+
+ while (count < noutput_items) { // Shift bits one at a time into header
+ if(slice(inbuf[count++]))
+ d_header = (d_header << 1) | 1;
+ else
+ d_header = d_header << 1;
+
+ if (++d_headerbitlen_cnt == HEADERBITLEN) {
+
+ if (VERBOSE)
+ fprintf(stderr, "got header: 0x%08x\n", d_header);
+
+ // we have a full header, check to see if it has been received properly
+ if (header_ok()){
+ int payload_len = header_payload_len();
+ if (payload_len <= MAX_PKT_LEN) // reasonable?
+ enter_have_header(payload_len); // yes.
+ else
+ enter_search(); // no.
+ }
+ else
+ enter_search(); // no.
+ break; // we're in a new state
+ }
+ }
+ break;
+
+ case STATE_HAVE_HEADER:
+ if (VERBOSE)
+ fprintf(stderr,"Packet Build\n"),fflush(stderr);
+
+ while (count < noutput_items) { // shift bits into bytes of packet one at a time
+ if(slice(inbuf[count++]))
+ d_packet_byte = (d_packet_byte << 1) | 1;
+ else
+ d_packet_byte = d_packet_byte << 1;
+
+ if (d_packet_byte_index++ == 7) { // byte is full so move to next byte
+ d_packet[d_packetlen_cnt++] = d_packet_byte;
+ d_packet_byte_index = 0;
+
+ if (d_packetlen_cnt == d_packetlen){ // packet is filled
+
+ // build a message
+ gr_message_sptr msg = gr_make_message(0, 0, 0, d_packetlen_cnt);
+ memcpy(msg->msg(), d_packet, d_packetlen_cnt);
+
+ d_target_queue->insert_tail(msg); // send it
+ msg.reset(); // free it up
+
+ enter_search();
+ break;
+ }
+ }
+ }
+ break;
+
+ default:
+ assert(0);
+
+ } // switch
+
+ } // while
+
+ return noutput_items;
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_packet_sink.h b/gnuradio-core/src/lib/general/gr_packet_sink.h
new file mode 100644
index 0000000000..3c468afd11
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_packet_sink.h
@@ -0,0 +1,111 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_PACKET_SINK_H
+#define INCLUDED_GR_PACKET_SINK_H
+
+#include <gr_sync_block.h>
+#include <gr_msg_queue.h>
+
+class gr_packet_sink;
+typedef boost::shared_ptr<gr_packet_sink> gr_packet_sink_sptr;
+
+gr_packet_sink_sptr
+gr_make_packet_sink (const std::vector<unsigned char>& sync_vector,
+ gr_msg_queue_sptr target_queue,
+ int threshold = -1 // -1 -> use default
+ );
+/*!
+ * \brief process received bits looking for packet sync, header, and process bits into packet
+ * \ingroup sink
+ */
+class gr_packet_sink : public gr_sync_block
+{
+ friend gr_packet_sink_sptr
+ gr_make_packet_sink (const std::vector<unsigned char>& sync_vector,
+ gr_msg_queue_sptr target_queue,
+ int threshold);
+
+ private:
+ enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER};
+
+ static const int MAX_PKT_LEN = 4096;
+ static const int HEADERBITLEN = 32;
+
+ gr_msg_queue_sptr d_target_queue; // where to send the packet when received
+ unsigned long long d_sync_vector; // access code to locate start of packet
+ unsigned int d_threshold; // how many bits may be wrong in sync vector
+
+ state_t d_state;
+
+ unsigned long long d_shift_reg; // used to look for sync_vector
+
+ unsigned int d_header; // header bits
+ int d_headerbitlen_cnt; // how many so far
+
+ unsigned char d_packet[MAX_PKT_LEN]; // assembled payload
+ unsigned char d_packet_byte; // byte being assembled
+ int d_packet_byte_index; // which bit of d_packet_byte we're working on
+ int d_packetlen; // length of packet
+ int d_packetlen_cnt; // how many so far
+
+ protected:
+ gr_packet_sink(const std::vector<unsigned char>& sync_vector,
+ gr_msg_queue_sptr target_queue,
+ int threshold);
+
+ void enter_search();
+ void enter_have_sync();
+ void enter_have_header(int payload_len);
+
+ int slice(float x) { return x > 0 ? 1 : 0; }
+
+ bool header_ok()
+ {
+ // confirm that two copies of header info are identical
+ return ((d_header >> 16) ^ (d_header & 0xffff)) == 0;
+ }
+
+ int header_payload_len()
+ {
+ // header consists of two 16-bit shorts in network byte order
+ int t = (d_header >> 16) & 0xffff;
+ return t;
+ }
+
+ public:
+ ~gr_packet_sink();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+
+ //! return true if we detect carrier
+ bool carrier_sensed() const
+ {
+ return d_state != STATE_SYNC_SEARCH;
+ }
+
+};
+
+#endif /* INCLUDED_GR_PACKET_SINK_H */
diff --git a/gnuradio-core/src/lib/general/gr_packet_sink.i b/gnuradio-core/src/lib/general/gr_packet_sink.i
new file mode 100644
index 0000000000..fb96072926
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,packet_sink)
+
+gr_packet_sink_sptr
+gr_make_packet_sink (const std::vector<unsigned char>& sync_vector,
+ gr_msg_queue_sptr target_queue,
+ int threshold = -1 // -1 -> use default
+ );
+
+class gr_packet_sink : public gr_sync_block
+{
+ protected:
+ gr_packet_sink (const std::vector<unsigned char>& sync_vector,
+ gr_msg_queue_sptr target_queue,
+ int threshold);
+ public:
+ ~gr_packet_sink ();
+
+ bool carrier_sensed() const;
+};
diff --git a/gnuradio-core/src/lib/general/gr_phase_modulator_fc.cc b/gnuradio-core/src/lib/general/gr_phase_modulator_fc.cc
new file mode 100644
index 0000000000..95631f09f7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_phase_modulator_fc.cc
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_phase_modulator_fc.h>
+#include <gr_io_signature.h>
+#include <gr_sincos.h>
+#include <math.h>
+
+
+gr_phase_modulator_fc_sptr gr_make_phase_modulator_fc (double sensitivity)
+{
+ return gr_phase_modulator_fc_sptr (new gr_phase_modulator_fc (sensitivity));
+}
+
+gr_phase_modulator_fc::gr_phase_modulator_fc (double sensitivity)
+ : gr_sync_block ("phase_modulator_fc",
+ gr_make_io_signature (1, 1, sizeof (float)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex))),
+ d_sensitivity (sensitivity), d_phase (0)
+{
+}
+
+int
+gr_phase_modulator_fc::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ for (int i = 0; i < noutput_items; i++){
+ d_phase = d_sensitivity * in[i];
+ float oi, oq;
+ gr_sincosf (d_phase, &oq, &oi);
+ out[i] = gr_complex (oi, oq);
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_phase_modulator_fc.h b/gnuradio-core/src/lib/general/gr_phase_modulator_fc.h
new file mode 100644
index 0000000000..ea27427524
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_phase_modulator_fc.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_PHASE_MODULATOR_FC_H
+#define INCLUDED_GR_PHASE_MODULATOR_FC_H
+
+#include <gr_sync_block.h>
+
+class gr_phase_modulator_fc;
+typedef boost::shared_ptr<gr_phase_modulator_fc> gr_phase_modulator_fc_sptr;
+
+gr_phase_modulator_fc_sptr gr_make_phase_modulator_fc (double sensitivity);
+
+/*!
+ * \brief Phase modulator block
+ * \ingroup block
+ * output=complex(cos(in*sensitivity),sin(in*sensitivity))
+ */
+class gr_phase_modulator_fc : public gr_sync_block
+{
+ double d_sensitivity;
+ double d_phase;
+
+ friend gr_phase_modulator_fc_sptr
+ gr_make_phase_modulator_fc (double sensitivity);
+
+ gr_phase_modulator_fc (double sensitivity);
+
+ public:
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_PHASE_MODULATOR_FC_H */
diff --git a/gnuradio-core/src/lib/general/gr_phase_modulator_fc.i b/gnuradio-core/src/lib/general/gr_phase_modulator_fc.i
new file mode 100644
index 0000000000..0ce25fd19c
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,phase_modulator_fc)
+
+gr_phase_modulator_fc_sptr gr_make_phase_modulator_fc (double sensitivity);
+
+class gr_phase_modulator_fc : public gr_sync_block
+{
+ private:
+ gr_phase_modulator_fc (double sensitivity);
+};
diff --git a/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.cc b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.cc
new file mode 100644
index 0000000000..4736e77cf4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.cc
@@ -0,0 +1,117 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pll_carriertracking_cc.h>
+#include <gr_io_signature.h>
+#include <gr_sincos.h>
+#include <math.h>
+
+#define M_TWOPI (2*M_PI)
+
+gr_pll_carriertracking_cc_sptr
+gr_make_pll_carriertracking_cc (float alpha, float beta, float max_freq, float min_freq)
+{
+ return gr_pll_carriertracking_cc_sptr (new gr_pll_carriertracking_cc (alpha, beta, max_freq, min_freq));
+}
+
+gr_pll_carriertracking_cc::gr_pll_carriertracking_cc (float alpha, float beta, float max_freq, float min_freq)
+ : gr_sync_block ("pll_carriertracking_cc",
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex))),
+ d_alpha(alpha), d_beta(beta),
+ d_max_freq(max_freq), d_min_freq(min_freq),
+ d_phase(0), d_freq((max_freq+min_freq)/2),
+ d_locksig(0),d_lock_threshold(0),d_squelch_enable(false)
+{
+}
+
+float
+gr_pll_carriertracking_cc::mod_2pi (float in)
+{
+ if(in>M_PI)
+ return in-M_TWOPI;
+ else if(in<-M_PI)
+ return in+M_TWOPI;
+ else
+ return in;
+}
+
+float
+gr_pll_carriertracking_cc::phase_detector(gr_complex sample,float ref_phase)
+{
+ float sample_phase;
+ sample_phase = atan2(sample.imag(),sample.real());
+ return mod_2pi(sample_phase-ref_phase);
+}
+
+bool
+gr_pll_carriertracking_cc::lock_detector(void)
+{
+ return (fabs(d_locksig) > d_lock_threshold);
+}
+
+bool
+gr_pll_carriertracking_cc::squelch_enable(bool set_squelch)
+{
+ return d_squelch_enable = set_squelch;
+}
+
+float
+gr_pll_carriertracking_cc::set_lock_threshold(float threshold)
+{
+ return d_lock_threshold = threshold;
+}
+
+int
+gr_pll_carriertracking_cc::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *iptr = (gr_complex *) input_items[0];
+ gr_complex *optr = (gr_complex *) output_items[0];
+
+ float error;
+ float t_imag, t_real;
+
+ for (int i = 0; i < noutput_items; i++){
+ error = phase_detector(iptr[i],d_phase);
+
+ d_freq = d_freq + d_beta * error;
+ d_phase = mod_2pi(d_phase + d_freq + d_alpha * error);
+
+ if (d_freq > d_max_freq)
+ d_freq = d_max_freq;
+ else if (d_freq < d_min_freq)
+ d_freq = d_min_freq;
+ gr_sincosf(d_phase,&t_imag,&t_real);
+ optr[i] = gr_complex(t_real,t_imag);
+ d_locksig = d_locksig * (1.0 - d_alpha) + d_alpha*(iptr[i].real() * t_real + iptr[i].imag() * t_imag);
+
+ if ((d_squelch_enable) && !lock_detector())
+ optr[i] = 0;
+ }
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.h b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.h
new file mode 100644
index 0000000000..679eb24d95
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.h
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,206 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_PLL_CARRIERTRACKING_CC_H
+#define INCLUDED_GR_PLL_CARRIERTRACKING_CC_H
+
+#include <gr_sync_block.h>
+
+class gr_pll_carriertracking_cc;
+typedef boost::shared_ptr<gr_pll_carriertracking_cc> gr_pll_carriertracking_cc_sptr;
+
+gr_pll_carriertracking_cc_sptr gr_make_pll_carriertracking_cc (float alpha, float beta,
+ float max_freq, float min_freq);
+/*!
+ * \brief Implements a PLL which locks to the input frequency and outputs the
+ * input signal mixed with that carrier.
+ * \ingroup block
+ *
+ * input: stream of complex; output: stream of complex
+ *
+ * This PLL locks onto a [possibly noisy] reference carrier on
+ * the input and outputs that signal, downconverted to DC
+ *
+ * All settings max_freq and min_freq are in terms of radians per sample,
+ * NOT HERTZ. Alpha is the phase gain (first order, units of radians per radian)
+ * and beta is the frequency gain (second order, units of radians per sample per radian)
+ * \sa gr_pll_freqdet_cf, gr_pll_carriertracking_cc
+ */
+
+class gr_pll_carriertracking_cc : public gr_sync_block
+{
+ friend gr_pll_carriertracking_cc_sptr gr_make_pll_carriertracking_cc (float alpha, float beta,
+ float max_freq, float min_freq);
+
+ float d_alpha,d_beta,d_max_freq,d_min_freq,d_phase,d_freq,d_locksig,d_lock_threshold;
+ bool d_squelch_enable;
+ gr_pll_carriertracking_cc (float alpha, float beta, float max_freq, float min_freq);
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+private:
+ float mod_2pi (float in);
+ float phase_detector(gr_complex sample,float ref_phase);
+public:
+ bool lock_detector(void);
+ bool squelch_enable(bool);
+ float set_lock_threshold(float);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.i b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.i
new file mode 100644
index 0000000000..2653f8e8a1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pll_carriertracking_cc);
+
+gr_pll_carriertracking_cc_sptr
+gr_make_pll_carriertracking_cc (float alpha, float beta,
+ float max_freq, float min_freq);
+
+class gr_pll_carriertracking_cc : public gr_sync_block
+{
+ private:
+ gr_pll_carriertracking_cc (float alpha, float beta, float max_freq, float min_freq);
+ public:
+ bool lock_detector(void);
+ bool squelch_enable(bool);
+ float set_lock_threshold(float);
+
+};
diff --git a/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.cc b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.cc
new file mode 100644
index 0000000000..f15f160dc0
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.cc
@@ -0,0 +1,94 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// WARNING: this file is machine generated. Edits will be over written
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pll_freqdet_cf.h>
+#include <gr_io_signature.h>
+#include <math.h>
+
+#define M_TWOPI (2*M_PI)
+
+gr_pll_freqdet_cf_sptr
+gr_make_pll_freqdet_cf (float alpha, float beta, float max_freq, float min_freq)
+{
+ return gr_pll_freqdet_cf_sptr (new gr_pll_freqdet_cf (alpha, beta, max_freq, min_freq));
+}
+
+gr_pll_freqdet_cf::gr_pll_freqdet_cf (float alpha, float beta, float max_freq, float min_freq)
+ : gr_sync_block ("pll_freqdet_cf",
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, sizeof (float))),
+ d_alpha(alpha), d_beta(beta),
+ d_max_freq(max_freq), d_min_freq(min_freq),
+ d_phase(0), d_freq((max_freq+min_freq)/2)
+{
+}
+
+float
+gr_pll_freqdet_cf::mod_2pi (float in)
+{
+ if(in>M_PI)
+ return in-M_TWOPI;
+ else if(in<-M_PI)
+ return in+M_TWOPI;
+ else
+ return in;
+}
+
+float
+gr_pll_freqdet_cf::phase_detector(gr_complex sample,float ref_phase)
+{
+ float sample_phase;
+ sample_phase = atan2(sample.imag(),sample.real());
+ return mod_2pi(sample_phase-ref_phase);
+}
+
+int
+gr_pll_freqdet_cf::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *iptr = (gr_complex *) input_items[0];
+ float *optr = (float *) output_items[0];
+
+ float error;
+ int size = noutput_items;
+
+ while (size-- > 0) {
+ error = phase_detector(*iptr++,d_phase);
+
+ d_freq = d_freq + d_beta * error;
+ d_phase = mod_2pi(d_phase + d_freq + d_alpha * error);
+
+ if (d_freq > d_max_freq)
+ d_freq = d_max_freq;
+ else if (d_freq < d_min_freq)
+ d_freq = d_min_freq;
+ *optr++ = d_freq;
+ }
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.h b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.h
new file mode 100644
index 0000000000..3d05a1c2c9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.h
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_PLL_FREQDET_CF_H
+#define INCLUDED_GR_PLL_FREQDET_CF_H
+
+#include <gr_sync_block.h>
+
+class gr_pll_freqdet_cf;
+typedef boost::shared_ptr<gr_pll_freqdet_cf> gr_pll_freqdet_cf_sptr;
+
+gr_pll_freqdet_cf_sptr gr_make_pll_freqdet_cf (float alpha, float beta,
+ float max_freq, float min_freq);
+/*!
+ * \brief Implements a PLL which locks to the input frequency and outputs
+ * an estimate of that frequency. Useful for FM Demod.
+ * \ingroup block
+ *
+ * input: stream of complex; output: stream of floats
+ *
+ * This PLL locks onto a [possibly noisy] reference carrier on
+ * the input and outputs an estimate of that frequency in radians per sample.
+ * All settings max_freq and min_freq are in terms of radians per sample,
+ * NOT HERTZ. Alpha is the phase gain (first order, units of radians per radian)
+ * and beta is the frequency gain (second order, units of radians per sample per radian)
+ * \sa gr_pll_refout_cc, gr_pll_carriertracking_cc
+ */
+
+class gr_pll_freqdet_cf : public gr_sync_block
+{
+ friend gr_pll_freqdet_cf_sptr gr_make_pll_freqdet_cf (float alpha, float beta,
+ float max_freq, float min_freq);
+
+ float d_alpha,d_beta,d_max_freq,d_min_freq,d_phase,d_freq;
+ gr_pll_freqdet_cf (float alpha, float beta, float max_freq, float min_freq);
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+private:
+ float mod_2pi (float in);
+ float phase_detector(gr_complex sample,float ref_phase);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.i b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.i
new file mode 100644
index 0000000000..8a27c4fd04
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pll_freqdet_cf)
+
+ gr_pll_freqdet_cf_sptr gr_make_pll_freqdet_cf (float alpha, float beta,
+ float max_freq, float min_freq);
+
+class gr_pll_freqdet_cf : public gr_sync_block
+{
+ private:
+ gr_pll_freqdet_cf (float alpha, float beta, float max_freq, float min_freq);
+};
diff --git a/gnuradio-core/src/lib/general/gr_pll_refout_cc.cc b/gnuradio-core/src/lib/general/gr_pll_refout_cc.cc
new file mode 100644
index 0000000000..e535611890
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pll_refout_cc.cc
@@ -0,0 +1,97 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// WARNING: this file is machine generated. Edits will be over written
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pll_refout_cc.h>
+#include <gr_io_signature.h>
+#include <gr_sincos.h>
+#include <math.h>
+
+#define M_TWOPI (2*M_PI)
+
+gr_pll_refout_cc_sptr
+gr_make_pll_refout_cc (float alpha, float beta, float max_freq, float min_freq)
+{
+ return gr_pll_refout_cc_sptr (new gr_pll_refout_cc (alpha, beta, max_freq, min_freq));
+}
+
+gr_pll_refout_cc::gr_pll_refout_cc (float alpha, float beta, float max_freq, float min_freq)
+ : gr_sync_block ("pll_refout_cc",
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex))),
+ d_alpha(alpha), d_beta(beta),
+ d_max_freq(max_freq), d_min_freq(min_freq),
+ d_phase(0), d_freq((max_freq+min_freq)/2)
+{
+}
+
+float
+gr_pll_refout_cc::mod_2pi (float in)
+{
+ if(in>M_PI)
+ return in-M_TWOPI;
+ else if(in<-M_PI)
+ return in+M_TWOPI;
+ else
+ return in;
+}
+
+float
+gr_pll_refout_cc::phase_detector(gr_complex sample,float ref_phase)
+{
+ float sample_phase;
+ sample_phase = atan2(sample.imag(),sample.real());
+ return mod_2pi(sample_phase-ref_phase);
+}
+
+int
+gr_pll_refout_cc::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *iptr = (gr_complex *) input_items[0];
+ gr_complex *optr = (gr_complex *) output_items[0];
+
+ float error;
+ float t_imag, t_real;
+ int size = noutput_items;
+
+ while (size-- > 0) {
+ error = phase_detector(*iptr++,d_phase);
+
+ d_freq = d_freq + d_beta * error;
+ d_phase = mod_2pi(d_phase + d_freq + d_alpha * error);
+
+ if (d_freq > d_max_freq)
+ d_freq = d_max_freq;
+ else if (d_freq < d_min_freq)
+ d_freq = d_min_freq;
+ gr_sincosf(d_phase,&t_imag,&t_real);
+ *optr++ = gr_complex(t_real,t_imag);
+ }
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_pll_refout_cc.h b/gnuradio-core/src/lib/general/gr_pll_refout_cc.h
new file mode 100644
index 0000000000..c46a65ee2e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pll_refout_cc.h
@@ -0,0 +1,66 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+
+#ifndef INCLUDED_GR_PLL_REFOUT_CC_H
+#define INCLUDED_GR_PLL_REFOUT_CC_H
+
+#include <gr_sync_block.h>
+
+class gr_pll_refout_cc;
+typedef boost::shared_ptr<gr_pll_refout_cc> gr_pll_refout_cc_sptr;
+
+gr_pll_refout_cc_sptr gr_make_pll_refout_cc (float alpha, float beta,
+ float max_freq, float min_freq);
+/*!
+ * \brief Implements a PLL which locks to the input frequency and outputs a carrier
+ * \ingroup block
+ *
+ * input: stream of complex; output: stream of complex
+ *
+ * This PLL locks onto a [possibly noisy] reference carrier on
+ * the input and outputs a clean version which is phase and frequency
+ * aligned to it.
+ *
+ * All settings max_freq and min_freq are in terms of radians per sample,
+ * NOT HERTZ. Alpha is the phase gain (first order, units of radians per radian)
+ * and beta is the frequency gain (second order, units of radians per sample per radian)
+ * \sa gr_pll_freqdet_cf, gr_pll_carriertracking_cc
+ */
+class gr_pll_refout_cc : public gr_sync_block
+{
+ friend gr_pll_refout_cc_sptr gr_make_pll_refout_cc (float alpha, float beta,
+ float max_freq, float min_freq);
+
+ float d_alpha,d_beta,d_max_freq,d_min_freq,d_phase,d_freq;
+ gr_pll_refout_cc (float alpha, float beta, float max_freq, float min_freq);
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+private:
+ float mod_2pi (float in);
+ float phase_detector(gr_complex sample,float ref_phase);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_pll_refout_cc.i b/gnuradio-core/src/lib/general/gr_pll_refout_cc.i
new file mode 100644
index 0000000000..8cb4fde8d6
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pll_refout_cc.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pll_refout_cc)
+
+ gr_pll_refout_cc_sptr gr_make_pll_refout_cc (float alpha, float beta,
+ float max_freq, float min_freq);
+
+class gr_pll_refout_cc : public gr_sync_block
+{
+ private:
+ gr_pll_refout_cc (float alpha, float beta, float max_freq, float min_freq);
+};
diff --git a/gnuradio-core/src/lib/general/gr_prefix.cc.in b/gnuradio-core/src/lib/general/gr_prefix.cc.in
new file mode 100644
index 0000000000..25c6960ca4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_prefix.cc.in
@@ -0,0 +1,29 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gr_prefix.h>
+
+const std::string
+gr_prefix()
+{
+ return "@prefix@";
+}
diff --git a/gnuradio-core/src/lib/general/gr_prefix.h b/gnuradio-core/src/lib/general/gr_prefix.h
new file mode 100644
index 0000000000..a521b619b3
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_prefix.h
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_PREFIX_H
+#define INCLUDED_GR_PREFIX_H
+
+#include <string>
+
+/*!
+ * \brief return ./configure --prefix argument. Typically /usr/local
+ */
+const std::string gr_prefix();
+
+
+#endif /* INCLUDED_GR_PREFIX_H */
diff --git a/gnuradio-core/src/lib/general/gr_prefix.i b/gnuradio-core/src/lib/general/gr_prefix.i
new file mode 100644
index 0000000000..04e1899a64
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_prefix.i
@@ -0,0 +1,5 @@
+/* -*- c++ -*- */
+
+%rename(prefix) gr_prefix;
+
+const std::string gr_prefix();
diff --git a/gnuradio-core/src/lib/general/gr_prefs.cc b/gnuradio-core/src/lib/general/gr_prefs.cc
new file mode 100644
index 0000000000..c9721f0f5e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_prefs.cc
@@ -0,0 +1,88 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_prefs.h>
+
+/*
+ * Stub implementations
+ */
+
+static gr_prefs s_default_singleton;
+static gr_prefs *s_singleton = &s_default_singleton;
+
+gr_prefs *
+gr_prefs::singleton()
+{
+ return s_singleton;
+}
+
+void
+gr_prefs::set_singleton(gr_prefs *p)
+{
+ s_singleton = p;
+}
+
+gr_prefs::~gr_prefs()
+{
+ // nop
+}
+
+bool
+gr_prefs::has_section(const std::string section)
+{
+ return false;
+}
+
+bool
+gr_prefs::has_option(const std::string section, const std::string option)
+{
+ return false;
+}
+
+const std::string
+gr_prefs::get_string(const std::string section, const std::string option, const std::string default_val)
+{
+ return default_val;
+}
+
+bool
+gr_prefs::get_bool(const std::string section, const std::string option, bool default_val)
+{
+ return default_val;
+}
+
+long
+gr_prefs::get_long(const std::string section, const std::string option, long default_val)
+{
+ return default_val;
+}
+
+double
+gr_prefs::get_double(const std::string section, const std::string option, double default_val)
+{
+ return default_val;
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_prefs.h b/gnuradio-core/src/lib/general/gr_prefs.h
new file mode 100644
index 0000000000..eaf74870c1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_prefs.h
@@ -0,0 +1,82 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_PREFS_H
+#define INCLUDED_GR_PREFS_H
+
+#include <string>
+
+/*!
+ * \brief Base class for representing user preferences a la windows INI files.
+ *
+ * The real implementation is in Python, and is accessable from C++
+ * via the magic of SWIG directors.
+ */
+
+class gr_prefs
+{
+public:
+ static gr_prefs *singleton();
+ static void set_singleton(gr_prefs *p);
+
+ virtual ~gr_prefs();
+
+ /*!
+ * \brief Does \p section exist?
+ */
+ virtual bool has_section(const std::string section);
+
+ /*!
+ * \brief Does \p option exist?
+ */
+ virtual bool has_option(const std::string section, const std::string option);
+
+ /*!
+ * \brief If option exists return associated value; else default_val.
+ */
+ virtual const std::string get_string(const std::string section,
+ const std::string option,
+ const std::string default_val);
+
+ /*!
+ * \brief If option exists and value can be converted to bool, return it; else default_val.
+ */
+ virtual bool get_bool(const std::string section,
+ const std::string option,
+ bool default_val);
+
+ /*!
+ * \brief If option exists and value can be converted to long, return it; else default_val.
+ */
+ virtual long get_long(const std::string section,
+ const std::string option,
+ long default_val);
+
+ /*!
+ * \brief If option exists and value can be converted to double, return it; else default_val.
+ */
+ virtual double get_double(const std::string section,
+ const std::string option,
+ double default_val);
+};
+
+
+#endif /* INCLUDED_GR_PREFS_H */
diff --git a/gnuradio-core/src/lib/general/gr_prefs.i b/gnuradio-core/src/lib/general/gr_prefs.i
new file mode 100644
index 0000000000..d11da173e3
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_prefs.i
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// Generate SWIG directors for gr_prefs.
+%feature("director") gr_prefs;
+
+class gr_prefs
+{
+public:
+ static gr_prefs *singleton();
+ static void set_singleton(gr_prefs *p);
+
+ virtual ~gr_prefs();
+
+ /*!
+ * \brief Does \p section exist?
+ */
+ virtual bool has_section(const std::string section);
+
+ /*!
+ * \brief Does \p option exist?
+ */
+ virtual bool has_option(const std::string section, const std::string option);
+
+ /*!
+ * \brief If option exists return associated value; else default_val.
+ */
+ virtual const std::string get_string(const std::string section,
+ const std::string option,
+ const std::string default_val);
+
+ /*!
+ * \brief If option exists and value can be converted to bool, return it; else default_val.
+ */
+ virtual bool get_bool(const std::string section,
+ const std::string option,
+ bool default_val);
+
+ /*!
+ * \brief If option exists and value can be converted to long, return it; else default_val.
+ */
+ virtual long get_long(const std::string section,
+ const std::string option,
+ long default_val);
+
+ /*!
+ * \brief If option exists and value can be converted to double, return it; else default_val.
+ */
+ virtual double get_double(const std::string section,
+ const std::string option,
+ double default_val);
+};
+
diff --git a/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.cc b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.cc
new file mode 100644
index 0000000000..73c7343b32
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.cc
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_probe_avg_mag_sqrd_c.h>
+#include <gr_io_signature.h>
+#include <cmath>
+
+gr_probe_avg_mag_sqrd_c_sptr
+gr_make_probe_avg_mag_sqrd_c(double threshold_db, double alpha)
+{
+ return gr_probe_avg_mag_sqrd_c_sptr(new gr_probe_avg_mag_sqrd_c(threshold_db, alpha));
+}
+
+gr_probe_avg_mag_sqrd_c::gr_probe_avg_mag_sqrd_c (double threshold_db, double alpha)
+ : gr_sync_block ("probe_avg_mag_sqrd_c",
+ gr_make_io_signature(1, 1, sizeof(gr_complex)),
+ gr_make_io_signature(0, 0, 0)),
+ d_iir(alpha), d_unmuted(false), d_level(0)
+{
+ set_threshold (threshold_db);
+}
+
+gr_probe_avg_mag_sqrd_c::~gr_probe_avg_mag_sqrd_c()
+{
+}
+
+
+int
+gr_probe_avg_mag_sqrd_c::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *in = (const gr_complex *) input_items[0];
+
+ for (int i = 0; i < noutput_items; i++){
+ double mag_sqrd = in[i].real()*in[i].real() + in[i].imag()*in[i].imag();
+ d_iir.filter(mag_sqrd); // computed for side effect: prev_output()
+ }
+
+ d_unmuted = d_iir.prev_output() >= d_threshold;
+ d_level = d_iir.prev_output();
+ return noutput_items;
+}
+
+double
+gr_probe_avg_mag_sqrd_c::threshold() const
+{
+ return 10 * std::log10(d_threshold);
+}
+
+void
+gr_probe_avg_mag_sqrd_c::set_threshold(double decibels)
+{
+ // convert to absolute threshold (mag squared)
+ d_threshold = std::pow(10.0, decibels/10);
+}
+
+void
+gr_probe_avg_mag_sqrd_c::set_alpha(double alpha)
+{
+ d_iir.set_taps(alpha);
+}
diff --git a/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.h b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.h
new file mode 100644
index 0000000000..85e2244b94
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.h
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_PROBE_AVG_MAG_SQRD_C_H
+#define INCLUDED_GR_PROBE_AVG_MAG_SQRD_C_H
+
+#include <gr_sync_block.h>
+#include <gr_single_pole_iir.h>
+
+class gr_probe_avg_mag_sqrd_c;
+typedef boost::shared_ptr<gr_probe_avg_mag_sqrd_c> gr_probe_avg_mag_sqrd_c_sptr;
+
+gr_probe_avg_mag_sqrd_c_sptr
+gr_make_probe_avg_mag_sqrd_c (double threshold_db, double alpha = 0.0001);
+
+/*!
+ * \brief compute avg magnitude squared.
+ * \ingroup sink
+ *
+ * input: gr_complex
+ *
+ * Compute a running average of the magnitude squared of the the input.
+ * The level and indication as to whether the level exceeds threshold
+ * can be retrieved with the level and unmuted accessors.
+ */
+class gr_probe_avg_mag_sqrd_c : public gr_sync_block
+{
+ double d_threshold;
+ gr_single_pole_iir<double,double,double> d_iir;
+ bool d_unmuted;
+ double d_level;
+
+ friend gr_probe_avg_mag_sqrd_c_sptr
+ gr_make_probe_avg_mag_sqrd_c (double threshold_db, double alpha);
+
+ gr_probe_avg_mag_sqrd_c (double threshold_db, double alpha);
+
+public:
+ ~gr_probe_avg_mag_sqrd_c ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ // ACCESSORS
+ bool unmuted () const { return d_unmuted; }
+ double level () const { return d_level; }
+
+ double threshold() const;
+
+ // SETTERS
+ void set_alpha (double alpha);
+ void set_threshold (double decibels);
+};
+
+#endif /* INCLUDED_GR_PROBE_AVG_MAG_SQRD_C_H */
diff --git a/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.i b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.i
new file mode 100644
index 0000000000..0b8000c52f
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,probe_avg_mag_sqrd_c);
+
+gr_probe_avg_mag_sqrd_c_sptr
+gr_make_probe_avg_mag_sqrd_c (double threshold_db, double alpha = 0.0001);
+
+class gr_probe_avg_mag_sqrd_c : public gr_sync_block
+{
+public:
+ bool unmuted () const { return d_unmuted; }
+ double level () const { return d_level; }
+ void set_alpha (double alpha);
+ void set_threshold (double decibels);
+ double threshold();
+};
diff --git a/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.cc b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.cc
new file mode 100644
index 0000000000..439138f059
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.cc
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_probe_avg_mag_sqrd_f.h>
+#include <gr_io_signature.h>
+#include <cmath>
+
+gr_probe_avg_mag_sqrd_f_sptr
+gr_make_probe_avg_mag_sqrd_f(double threshold_db, double alpha)
+{
+ return gr_probe_avg_mag_sqrd_f_sptr(new gr_probe_avg_mag_sqrd_f(threshold_db, alpha));
+}
+
+gr_probe_avg_mag_sqrd_f::gr_probe_avg_mag_sqrd_f (double threshold_db, double alpha)
+ : gr_sync_block ("probe_avg_mag_sqrd_f",
+ gr_make_io_signature(1, 1, sizeof(float)),
+ gr_make_io_signature(0, 0, 0)),
+ d_iir(alpha), d_unmuted(false), d_level(0)
+{
+ set_threshold (threshold_db);
+}
+
+gr_probe_avg_mag_sqrd_f::~gr_probe_avg_mag_sqrd_f()
+{
+}
+
+
+int
+gr_probe_avg_mag_sqrd_f::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+
+ for (int i = 0; i < noutput_items; i++){
+ double mag_sqrd = in[i]*in[i];
+ d_iir.filter(mag_sqrd); // computed for side effect: prev_output()
+ }
+
+ d_unmuted = d_iir.prev_output() >= d_threshold;
+ d_level = d_iir.prev_output();
+ return noutput_items;
+}
+
+double
+gr_probe_avg_mag_sqrd_f::threshold() const
+{
+ return 10 * std::log10(d_threshold);
+}
+
+void
+gr_probe_avg_mag_sqrd_f::set_threshold(double decibels)
+{
+ // convert to absolute threshold (mag sqrd)
+ d_threshold = std::pow(10.0, decibels/10);
+}
+
+void
+gr_probe_avg_mag_sqrd_f::set_alpha(double alpha)
+{
+ d_iir.set_taps(alpha);
+}
diff --git a/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.h b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.h
new file mode 100644
index 0000000000..5f20a5ca82
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.h
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_PROBE_AVG_MAG_SQRD_F_H
+#define INCLUDED_GR_PROBE_AVG_MAG_SQRD_F_H
+
+#include <gr_sync_block.h>
+#include <gr_single_pole_iir.h>
+
+class gr_probe_avg_mag_sqrd_f;
+typedef boost::shared_ptr<gr_probe_avg_mag_sqrd_f> gr_probe_avg_mag_sqrd_f_sptr;
+
+gr_probe_avg_mag_sqrd_f_sptr
+gr_make_probe_avg_mag_sqrd_f (double threshold_db, double alpha = 0.0001);
+
+/*!
+ * \brief compute avg magnitude squared.
+ * \ingroup sink
+ *
+ * input: float
+ *
+ * Compute a running average of the magnitude squared of the the input.
+ * The level and indication as to whether the level exceeds threshold
+ * can be retrieved with the level and unmuted accessors.
+ */
+class gr_probe_avg_mag_sqrd_f : public gr_sync_block
+{
+ double d_threshold;
+ gr_single_pole_iir<double,double,double> d_iir;
+ bool d_unmuted;
+ double d_level;
+
+ friend gr_probe_avg_mag_sqrd_f_sptr
+ gr_make_probe_avg_mag_sqrd_f (double threshold_db, double alpha);
+
+ gr_probe_avg_mag_sqrd_f (double threshold_db, double alpha);
+
+public:
+ ~gr_probe_avg_mag_sqrd_f ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ // ACCESSORS
+ bool unmuted () const { return d_unmuted; }
+ double level () const { return d_level; }
+
+ double threshold() const;
+
+ // SETTERS
+ void set_alpha (double alpha);
+ void set_threshold (double decibels);
+};
+
+#endif /* INCLUDED_GR_PROBE_AVG_MAG_SQRD_F_H */
diff --git a/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.i b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.i
new file mode 100644
index 0000000000..f58caa2d44
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,probe_avg_mag_sqrd_f);
+
+gr_probe_avg_mag_sqrd_f_sptr
+gr_make_probe_avg_mag_sqrd_f (double threshold_db, double alpha = 0.0001);
+
+class gr_probe_avg_mag_sqrd_f : public gr_sync_block
+{
+public:
+ bool unmuted () const { return d_unmuted; }
+ double level () const { return d_level; }
+ double threshold() const;
+ void set_alpha (double alpha);
+ void set_threshold (double decibels);
+};
diff --git a/gnuradio-core/src/lib/general/gr_probe_signal_f.cc b/gnuradio-core/src/lib/general/gr_probe_signal_f.cc
new file mode 100644
index 0000000000..8c94b0367d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_probe_signal_f.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_probe_signal_f.h>
+#include <gr_io_signature.h>
+
+gr_probe_signal_f_sptr
+gr_make_probe_signal_f()
+{
+ return gr_probe_signal_f_sptr(new gr_probe_signal_f());
+}
+
+gr_probe_signal_f::gr_probe_signal_f ()
+ : gr_sync_block ("probe_signal_f",
+ gr_make_io_signature(1, 1, sizeof(float)),
+ gr_make_io_signature(0, 0, 0)),
+ d_level(0)
+{
+}
+
+gr_probe_signal_f::~gr_probe_signal_f()
+{
+}
+
+
+int
+gr_probe_signal_f::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+
+ if (noutput_items > 0)
+ d_level = in[noutput_items-1];
+
+ return noutput_items;
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_probe_signal_f.h b/gnuradio-core/src/lib/general/gr_probe_signal_f.h
new file mode 100644
index 0000000000..72811b20f1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_probe_signal_f.h
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_PROBE_SIGNAL_F_H
+#define INCLUDED_GR_PROBE_SIGNAL_F_H
+
+#include <gr_sync_block.h>
+
+class gr_probe_signal_f;
+typedef boost::shared_ptr<gr_probe_signal_f> gr_probe_signal_f_sptr;
+
+gr_probe_signal_f_sptr
+gr_make_probe_signal_f ();
+
+/*!
+ * \brief Sink that allows a sample to be grabbed from Python.
+ * \ingroup sink
+ */
+class gr_probe_signal_f : public gr_sync_block
+{
+ float d_level;
+
+ friend gr_probe_signal_f_sptr
+ gr_make_probe_signal_f();
+
+ gr_probe_signal_f();
+
+public:
+ ~gr_probe_signal_f();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ float level() const { return d_level; }
+
+};
+
+#endif /* INCLUDED_GR_PROBE_SIGNAL_F_H */
diff --git a/gnuradio-core/src/lib/general/gr_probe_signal_f.i b/gnuradio-core/src/lib/general/gr_probe_signal_f.i
new file mode 100644
index 0000000000..14fc6f1941
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_probe_signal_f.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,probe_signal_f);
+
+gr_probe_signal_f_sptr
+gr_make_probe_signal_f ();
+
+class gr_probe_signal_f : public gr_sync_block
+{
+public:
+ float level () const { return d_level; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_pwr_squelch_cc.cc b/gnuradio-core/src/lib/general/gr_pwr_squelch_cc.cc
new file mode 100644
index 0000000000..33c128725e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pwr_squelch_cc.cc
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pwr_squelch_cc.h>
+
+gr_pwr_squelch_cc_sptr
+gr_make_pwr_squelch_cc(double threshold, double alpha, int ramp, bool gate)
+{
+ return gr_pwr_squelch_cc_sptr(new gr_pwr_squelch_cc(threshold, alpha, ramp, gate));
+}
+
+gr_pwr_squelch_cc::gr_pwr_squelch_cc(double threshold, double alpha, int ramp, bool gate) :
+ gr_squelch_base_cc("pwr_squelch_cc", ramp, gate),
+ d_iir(alpha)
+{
+ set_threshold(threshold);
+}
+
+std::vector<float> gr_pwr_squelch_cc::squelch_range() const
+{
+ std::vector<float> r(3);
+ r[0] = -50.0; // min FIXME
+ r[1] = +50.0; // max FIXME
+ r[2] = (r[1] - r[0]) / 100; // step size
+
+ return r;
+}
+
+void gr_pwr_squelch_cc::update_state(const gr_complex &in)
+{
+ d_pwr = d_iir.filter(in.real()*in.real()+in.imag()*in.imag());
+}
diff --git a/gnuradio-core/src/lib/general/gr_pwr_squelch_cc.h b/gnuradio-core/src/lib/general/gr_pwr_squelch_cc.h
new file mode 100644
index 0000000000..2822ee5990
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pwr_squelch_cc.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_PWR_SQUELCH_CC_H
+#define INCLUDED_GR_PWR_SQUELCH_CC_H
+
+#include <cmath>
+#include <gr_squelch_base_cc.h>
+#include <gr_single_pole_iir.h>
+
+class gr_pwr_squelch_cc;
+typedef boost::shared_ptr<gr_pwr_squelch_cc> gr_pwr_squelch_cc_sptr;
+
+gr_pwr_squelch_cc_sptr
+gr_make_pwr_squelch_cc(double db, double alpha = 0.0001, int ramp=0, bool gate=false);
+
+/*!
+ * \brief gate or zero output when input power below threshold
+ * \ingroup block
+ */
+class gr_pwr_squelch_cc : public gr_squelch_base_cc
+{
+private:
+ double d_threshold;
+ double d_pwr;
+ gr_single_pole_iir<double,double,double> d_iir;
+
+ friend gr_pwr_squelch_cc_sptr gr_make_pwr_squelch_cc(double db, double alpha, int ramp, bool gate);
+ gr_pwr_squelch_cc(double db, double alpha, int ramp, bool gate);
+
+protected:
+ virtual void update_state(const gr_complex &in);
+ virtual bool mute() const { return d_pwr < d_threshold; }
+
+public:
+ std::vector<float> squelch_range() const;
+
+ double threshold() const { return 10*log10(d_threshold); }
+ void set_threshold(double db) { d_threshold = std::pow(10.0, db/10); }
+ void set_alpha(double alpha) { d_iir.set_taps(alpha); }
+};
+
+#endif /* INCLUDED_GR_PWR_SQUELCH_CC_H */
diff --git a/gnuradio-core/src/lib/general/gr_pwr_squelch_cc.i b/gnuradio-core/src/lib/general/gr_pwr_squelch_cc.i
new file mode 100644
index 0000000000..41832ab746
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pwr_squelch_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pwr_squelch_cc);
+
+%include gr_squelch_base_cc.i
+
+gr_pwr_squelch_cc_sptr
+gr_make_pwr_squelch_cc(double db, double alpha=0.0001, int ramp=0, bool gate=false);
+
+class gr_pwr_squelch_cc : public gr_squelch_base_cc
+{
+private:
+ gr_pwr_squelch_cc(double db, double alpha, int ramp, bool gate);
+
+public:
+ double threshold() const { return 10*log10(d_threshold); }
+ void set_threshold(double db) { d_threshold = std::pow(10.0, db/10); }
+ void set_alpha(double alpha) { d_iir.set_taps(alpha); }
+ std::vector<float> squelch_range() const;
+};
diff --git a/gnuradio-core/src/lib/general/gr_pwr_squelch_ff.cc b/gnuradio-core/src/lib/general/gr_pwr_squelch_ff.cc
new file mode 100644
index 0000000000..8bc3aad6c7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pwr_squelch_ff.cc
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pwr_squelch_ff.h>
+
+gr_pwr_squelch_ff_sptr
+gr_make_pwr_squelch_ff(double threshold, double alpha, int ramp, bool gate)
+{
+ return gr_pwr_squelch_ff_sptr(new gr_pwr_squelch_ff(threshold, alpha, ramp, gate));
+}
+
+gr_pwr_squelch_ff::gr_pwr_squelch_ff(double threshold, double alpha, int ramp, bool gate) :
+ gr_squelch_base_ff("pwr_squelch_ff", ramp, gate),
+ d_iir(alpha)
+{
+ set_threshold(threshold);
+}
+
+std::vector<float> gr_pwr_squelch_ff::squelch_range() const
+{
+ std::vector<float> r(3);
+ r[0] = -50.0; // min FIXME
+ r[1] = +50.0; // max FIXME
+ r[2] = (r[1] - r[0]) / 100; // step size
+
+ return r;
+}
+
+void gr_pwr_squelch_ff::update_state(const float &in)
+{
+ d_pwr = d_iir.filter(in*in);
+}
diff --git a/gnuradio-core/src/lib/general/gr_pwr_squelch_ff.h b/gnuradio-core/src/lib/general/gr_pwr_squelch_ff.h
new file mode 100644
index 0000000000..1eb61b160d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pwr_squelch_ff.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_PWR_SQUELCH_FF_H
+#define INCLUDED_GR_PWR_SQUELCH_FF_H
+
+#include <cmath>
+#include <gr_squelch_base_ff.h>
+#include <gr_single_pole_iir.h>
+
+class gr_pwr_squelch_ff;
+typedef boost::shared_ptr<gr_pwr_squelch_ff> gr_pwr_squelch_ff_sptr;
+
+gr_pwr_squelch_ff_sptr
+gr_make_pwr_squelch_ff(double db, double alpha = 0.0001, int ramp=0, bool gate=false);
+
+/*!
+ * \brief gate or zero output when input power below threshold
+ * \ingroup block
+ */
+class gr_pwr_squelch_ff : public gr_squelch_base_ff
+{
+private:
+ double d_threshold;
+ double d_pwr;
+ gr_single_pole_iir<double,double,double> d_iir;
+
+ friend gr_pwr_squelch_ff_sptr gr_make_pwr_squelch_ff(double db, double alpha, int ramp, bool gate);
+ gr_pwr_squelch_ff(double db, double alpha, int ramp, bool gate);
+
+protected:
+ virtual void update_state(const float &in);
+ virtual bool mute() const { return d_pwr < d_threshold; }
+
+public:
+ std::vector<float> squelch_range() const;
+
+ double threshold() const { return 10*log10(d_threshold); }
+ void set_threshold(double db) { d_threshold = std::pow(10.0, db/10); }
+ void set_alpha(double alpha) { d_iir.set_taps(alpha); }
+};
+
+#endif /* INCLUDED_GR_PWR_SQUELCH_FF_H */
diff --git a/gnuradio-core/src/lib/general/gr_pwr_squelch_ff.i b/gnuradio-core/src/lib/general/gr_pwr_squelch_ff.i
new file mode 100644
index 0000000000..4bc16b1061
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pwr_squelch_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pwr_squelch_ff);
+
+%include gr_squelch_base_ff.i
+
+gr_pwr_squelch_ff_sptr
+gr_make_pwr_squelch_ff(double db, double alpha=0.0001, int ramp=0, bool gate=false);
+
+class gr_pwr_squelch_ff : public gr_squelch_base_ff
+{
+private:
+ gr_pwr_squelch_ff(double db, double alpha, int ramp, bool gate);
+
+public:
+ double threshold() const { return 10*log10(d_threshold); }
+ void set_threshold(double db) { d_threshold = std::pow(10.0, db/10); }
+ void set_alpha(double alpha) { d_iir.set_taps(alpha); }
+ std::vector<float> squelch_range() const;
+};
diff --git a/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.cc b/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.cc
new file mode 100644
index 0000000000..eb1fae8575
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.cc
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_quadrature_demod_cf.h>
+#include <gr_io_signature.h>
+#include <gr_math.h>
+
+gr_quadrature_demod_cf::gr_quadrature_demod_cf (float gain)
+ : gr_sync_block ("quadrature_demod_cf",
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, sizeof (float))),
+ d_gain (gain)
+{
+ set_history (2); // we need to look at the previous value
+}
+
+gr_quadrature_demod_cf_sptr
+gr_make_quadrature_demod_cf (float gain)
+{
+ return gr_quadrature_demod_cf_sptr (new gr_quadrature_demod_cf (gain));
+}
+
+int
+gr_quadrature_demod_cf::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ gr_complex *in = (gr_complex *) input_items[0];
+ float *out = (float *) output_items[0];
+ in++; // ensure that in[-1] is valid
+
+ for (int i = 0; i < noutput_items; i++){
+ gr_complex product = in[i] * conj (in[i-1]);
+ // out[i] = d_gain * arg (product);
+ out[i] = d_gain * gr_fast_atan2f(imag(product), real(product));
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.h b/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.h
new file mode 100644
index 0000000000..7e625e7ad1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_QUADRATURE_DEMOD_CF_H
+#define INCLUDED_GR_QUADRATURE_DEMOD_CF_H
+
+#include <gr_sync_block.h>
+
+class gr_quadrature_demod_cf;
+typedef boost::shared_ptr<gr_quadrature_demod_cf> gr_quadrature_demod_cf_sptr;
+gr_quadrature_demod_cf_sptr gr_make_quadrature_demod_cf (float gain);
+
+/*!
+ * \brief quadrature demodulator: complex in, float out
+ * \ingroup block
+ *
+ * This can be used to demod FM, FSK, GMSK, etc.
+ * The input is complex baseband.
+ */
+class gr_quadrature_demod_cf : public gr_sync_block
+{
+ friend gr_quadrature_demod_cf_sptr gr_make_quadrature_demod_cf (float gain);
+ gr_quadrature_demod_cf (float gain);
+
+ float d_gain;
+
+ public:
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_QUADRATURE_DEMOD_CF_H */
diff --git a/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.i b/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.i
new file mode 100644
index 0000000000..685b278f1a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC (gr, quadrature_demod_cf)
+
+gr_quadrature_demod_cf_sptr gr_make_quadrature_demod_cf (float gain);
+
+class gr_quadrature_demod_cf : public gr_sync_block
+{
+ gr_quadrature_demod_cf (float gain);
+};
diff --git a/gnuradio-core/src/lib/general/gr_random.cc b/gnuradio-core/src/lib/general/gr_random.cc
new file mode 100644
index 0000000000..a56f2875b5
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_random.cc
@@ -0,0 +1,180 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Copyright 1997 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. M.I.T. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ */
+
+#include <math.h>
+#include <gr_random.h>
+
+#define IA 16807
+#define IM 2147483647
+#define AM (1.0/IM)
+#define IQ 127773
+#define IR 2836
+#define NDIV (1+(IM-1)/NTAB)
+#define EPS 1.2e-7
+#define RNMX (1.0-EPS)
+
+
+gr_random::gr_random (long seed)
+{
+ reseed (seed);
+}
+
+void
+gr_random::reseed (long seed)
+{
+ d_seed = seed;
+ d_iy = 0;
+ for (int i = 0; i < NTAB; i++)
+ d_iv[i] = 0;
+ d_iset = 0;
+ d_gset = 0;
+}
+
+/*
+ * This looks like it returns a uniform random deviate between 0.0 and 1.0
+ * It looks similar to code from "Numerical Recipes in C".
+ */
+float gr_random::ran1()
+{
+ int j;
+ long k;
+ float temp;
+
+ if (d_seed <= 0 || !d_iy) {
+ if (-d_seed < 1)
+ d_seed=1;
+ else
+ d_seed = -d_seed;
+ for (j=NTAB+7;j>=0;j--) {
+ k=d_seed/IQ;
+ d_seed=IA*(d_seed-k*IQ)-IR*k;
+ if (d_seed < 0)
+ d_seed += IM;
+ if (j < NTAB)
+ d_iv[j] = d_seed;
+ }
+ d_iy=d_iv[0];
+ }
+ k=(d_seed)/IQ;
+ d_seed=IA*(d_seed-k*IQ)-IR*k;
+ if (d_seed < 0)
+ d_seed += IM;
+ j=d_iy/NDIV;
+ d_iy=d_iv[j];
+ d_iv[j] = d_seed;
+ temp=AM * d_iy;
+ if (temp > RNMX)
+ temp = RNMX;
+ return temp;
+}
+
+/*
+ * Returns a normally distributed deviate with zero mean and variance 1.
+ * Also looks like it's from "Numerical Recipes in C".
+ */
+float gr_random::gasdev()
+{
+ float fac,rsq,v1,v2;
+ d_iset = 1 - d_iset;
+ if (d_iset) {
+ do {
+ v1=2.0*ran1()-1.0;
+ v2=2.0*ran1()-1.0;
+ rsq=v1*v1+v2*v2;
+ } while (rsq >= 1.0 || rsq == 0.0);
+ fac= sqrt(-2.0*log(rsq)/rsq);
+ d_gset=v1*fac;
+ return v2*fac;
+ }
+ return d_gset;
+}
+
+/*
+ * Copied from The KC7WW / OH2BNS Channel Simulator
+ * FIXME Need to check how good this is at some point
+ */
+
+float gr_random::laplacian()
+{
+ float z = ran1();
+ if (z < 0.5)
+ return log(2.0 * z) / M_SQRT2;
+ else
+ return -log(2.0 * (1.0 - z)) / M_SQRT2;
+}
+
+/*
+ * Copied from The KC7WW / OH2BNS Channel Simulator
+ * FIXME Need to check how good this is at some point
+ */
+
+ // 5 => scratchy, 8 => Geiger
+
+float gr_random::impulse(float factor = 5)
+{
+ float z = -M_SQRT2 * log(ran1());
+ if (fabsf(z) <= factor)
+ return 0.0;
+ else
+ return z;
+}
+
+/*
+ * Complex rayleigh is really gaussian I and gaussian Q
+ * It can also be generated by real rayleigh magnitude and
+ * uniform random angle
+ * Adapted from The KC7WW / OH2BNS Channel Simulator
+ * FIXME Need to check how good this is at some point
+ */
+
+gr_complex gr_random::rayleigh_complex()
+{
+ return gr_complex(gasdev(),gasdev());
+}
+
+/* Other option
+ mag = rayleigh();
+ ang = 2.0 * M_PI * RNG();
+ *Rx = rxx * cos(z);
+ *Iy = rxx * sin(z);
+*/
+
+
+float gr_random::rayleigh()
+{
+ return sqrt(-2.0 * log(ran1()));
+}
diff --git a/gnuradio-core/src/lib/general/gr_random.h b/gnuradio-core/src/lib/general/gr_random.h
new file mode 100644
index 0000000000..9726ee9b83
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_random.h
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_RANDOM_H
+#define INCLUDED_GR_RANDOM_H
+
+#include <gr_complex.h>
+
+/*!
+ * \brief pseudo random number generator
+ */
+class gr_random {
+protected:
+ static const int NTAB = 32;
+ long d_seed;
+ long d_iy;
+ long d_iv[NTAB];
+ int d_iset;
+ float d_gset;
+
+
+public:
+ gr_random (long seed=3021);
+
+ void reseed (long seed);
+
+ /*!
+ * \brief uniform random deviate in the range [0.0, 1.0)
+ */
+ float ran1 ();
+
+ /*!
+ * \brief normally distributed deviate with zero mean and variance 1
+ */
+ float gasdev ();
+
+ float laplacian ();
+ float impulse (float factor);
+ float rayleigh ();
+ gr_complex rayleigh_complex ();
+};
+
+#endif /* INCLUDED_GR_RANDOM_H */
+
diff --git a/gnuradio-core/src/lib/general/gr_remez.cc b/gnuradio-core/src/lib/general/gr_remez.cc
new file mode 100644
index 0000000000..1003900068
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_remez.cc
@@ -0,0 +1,1031 @@
+/**************************************************************************
+ * Parks-McClellan algorithm for FIR filter design (C version)
+ *-------------------------------------------------
+ * Copyright (c) 1995,1998 Jake Janovetz (janovetz@uiuc.edu)
+ * Copyright (c) 2004 Free Software Foundation, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ * Sep 1999 - Paul Kienzle (pkienzle@cs.indiana.edu)
+ * Modified for use in octave as a replacement for the matlab function
+ * remez.mex. In particular, magnitude responses are required for all
+ * band edges rather than one per band, griddensity is a parameter,
+ * and errors are returned rather than printed directly.
+ * Mar 2000 - Kai Habel (kahacjde@linux.zrz.tu-berlin.de)
+ * Change: ColumnVector x=arg(i).vector_value();
+ * to: ColumnVector x(arg(i).vector_value());
+ * There appear to be some problems with the routine Search. See comments
+ * therein [search for PAK:]. I haven't looked closely at the rest
+ * of the code---it may also have some problems.
+ *************************************************************************/
+
+/*
+ * This code was extracted from octave.sf.net, and wrapped with
+ * GNU Radio glue.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_remez.h>
+#include <cmath>
+#include <assert.h>
+#include <iostream>
+
+
+#ifndef LOCAL_BUFFER
+#include <vector>
+#define LOCAL_BUFFER(T, buf, size) \
+ std::vector<T> buf ## _vector (size); \
+ T *buf = &(buf ## _vector[0])
+#endif
+
+
+#define CONST const
+#define BANDPASS 1
+#define DIFFERENTIATOR 2
+#define HILBERT 3
+
+#define NEGATIVE 0
+#define POSITIVE 1
+
+#define Pi 3.14159265358979323846
+#define Pi2 (2*Pi)
+
+#define GRIDDENSITY 16
+#define MAXITERATIONS 40
+
+/*******************
+ * CreateDenseGrid
+ *=================
+ * Creates the dense grid of frequencies from the specified bands.
+ * Also creates the Desired Frequency Response function (D[]) and
+ * the Weight function (W[]) on that dense grid
+ *
+ *
+ * INPUT:
+ * ------
+ * int r - 1/2 the number of filter coefficients
+ * int numtaps - Number of taps in the resulting filter
+ * int numband - Number of bands in user specification
+ * double bands[] - User-specified band edges [2*numband]
+ * double des[] - Desired response per band [2*numband]
+ * double weight[] - Weight per band [numband]
+ * int symmetry - Symmetry of filter - used for grid check
+ * int griddensity
+ *
+ * OUTPUT:
+ * -------
+ * int gridsize - Number of elements in the dense frequency grid
+ * double Grid[] - Frequencies (0 to 0.5) on the dense grid [gridsize]
+ * double D[] - Desired response on the dense grid [gridsize]
+ * double W[] - Weight function on the dense grid [gridsize]
+ *******************/
+
+static void
+CreateDenseGrid (int r, int numtaps, int numband, const double bands[],
+ const double des[], const double weight[], int gridsize,
+ double Grid[], double D[], double W[],
+ int symmetry, int griddensity)
+{
+ int i, j, k, band;
+ double delf, lowf, highf, grid0;
+
+ delf = 0.5/(griddensity*r);
+
+/*
+ * For differentiator, hilbert,
+ * symmetry is odd and Grid[0] = max(delf, bands[0])
+ */
+ grid0 = (symmetry == NEGATIVE) && (delf > bands[0]) ? delf : bands[0];
+
+ j=0;
+ for (band=0; band < numband; band++)
+ {
+ lowf = (band==0 ? grid0 : bands[2*band]);
+ highf = bands[2*band + 1];
+ k = (int)((highf - lowf)/delf + 0.5); /* .5 for rounding */
+ for (i=0; i<k; i++)
+ {
+ D[j] = des[2*band] + i*(des[2*band+1]-des[2*band])/(k-1);
+ W[j] = weight[band];
+ Grid[j] = lowf;
+ lowf += delf;
+ j++;
+ }
+ Grid[j-1] = highf;
+ }
+
+/*
+ * Similar to above, if odd symmetry, last grid point can't be .5
+ * - but, if there are even taps, leave the last grid point at .5
+ */
+ if ((symmetry == NEGATIVE) &&
+ (Grid[gridsize-1] > (0.5 - delf)) &&
+ (numtaps % 2))
+ {
+ Grid[gridsize-1] = 0.5-delf;
+ }
+}
+
+
+/********************
+ * InitialGuess
+ *==============
+ * Places Extremal Frequencies evenly throughout the dense grid.
+ *
+ *
+ * INPUT:
+ * ------
+ * int r - 1/2 the number of filter coefficients
+ * int gridsize - Number of elements in the dense frequency grid
+ *
+ * OUTPUT:
+ * -------
+ * int Ext[] - Extremal indexes to dense frequency grid [r+1]
+ ********************/
+
+static void
+InitialGuess (int r, int Ext[], int gridsize)
+{
+ int i;
+
+ for (i=0; i<=r; i++)
+ Ext[i] = i * (gridsize-1) / r;
+}
+
+
+/***********************
+ * CalcParms
+ *===========
+ *
+ *
+ * INPUT:
+ * ------
+ * int r - 1/2 the number of filter coefficients
+ * int Ext[] - Extremal indexes to dense frequency grid [r+1]
+ * double Grid[] - Frequencies (0 to 0.5) on the dense grid [gridsize]
+ * double D[] - Desired response on the dense grid [gridsize]
+ * double W[] - Weight function on the dense grid [gridsize]
+ *
+ * OUTPUT:
+ * -------
+ * double ad[] - 'b' in Oppenheim & Schafer [r+1]
+ * double x[] - [r+1]
+ * double y[] - 'C' in Oppenheim & Schafer [r+1]
+ ***********************/
+
+static void
+CalcParms (int r, int Ext[], double Grid[], double D[], double W[],
+ double ad[], double x[], double y[])
+{
+ int i, j, k, ld;
+ double sign, xi, delta, denom, numer;
+
+/*
+ * Find x[]
+ */
+ for (i=0; i<=r; i++)
+ x[i] = cos(Pi2 * Grid[Ext[i]]);
+
+/*
+ * Calculate ad[] - Oppenheim & Schafer eq 7.132
+ */
+ ld = (r-1)/15 + 1; /* Skips around to avoid round errors */
+ for (i=0; i<=r; i++)
+ {
+ denom = 1.0;
+ xi = x[i];
+ for (j=0; j<ld; j++)
+ {
+ for (k=j; k<=r; k+=ld)
+ if (k != i)
+ denom *= 2.0*(xi - x[k]);
+ }
+ if (fabs(denom)<0.00001)
+ denom = 0.00001;
+ ad[i] = 1.0/denom;
+ }
+
+/*
+ * Calculate delta - Oppenheim & Schafer eq 7.131
+ */
+ numer = denom = 0;
+ sign = 1;
+ for (i=0; i<=r; i++)
+ {
+ numer += ad[i] * D[Ext[i]];
+ denom += sign * ad[i]/W[Ext[i]];
+ sign = -sign;
+ }
+ delta = numer/denom;
+ sign = 1;
+
+/*
+ * Calculate y[] - Oppenheim & Schafer eq 7.133b
+ */
+ for (i=0; i<=r; i++)
+ {
+ y[i] = D[Ext[i]] - sign * delta/W[Ext[i]];
+ sign = -sign;
+ }
+}
+
+
+/*********************
+ * ComputeA
+ *==========
+ * Using values calculated in CalcParms, ComputeA calculates the
+ * actual filter response at a given frequency (freq). Uses
+ * eq 7.133a from Oppenheim & Schafer.
+ *
+ *
+ * INPUT:
+ * ------
+ * double freq - Frequency (0 to 0.5) at which to calculate A
+ * int r - 1/2 the number of filter coefficients
+ * double ad[] - 'b' in Oppenheim & Schafer [r+1]
+ * double x[] - [r+1]
+ * double y[] - 'C' in Oppenheim & Schafer [r+1]
+ *
+ * OUTPUT:
+ * -------
+ * Returns double value of A[freq]
+ *********************/
+
+static double
+ComputeA (double freq, int r, double ad[], double x[], double y[])
+{
+ int i;
+ double xc, c, denom, numer;
+
+ denom = numer = 0;
+ xc = cos(Pi2 * freq);
+ for (i=0; i<=r; i++)
+ {
+ c = xc - x[i];
+ if (fabs(c) < 1.0e-7)
+ {
+ numer = y[i];
+ denom = 1;
+ break;
+ }
+ c = ad[i]/c;
+ denom += c;
+ numer += c*y[i];
+ }
+ return numer/denom;
+}
+
+
+/************************
+ * CalcError
+ *===========
+ * Calculates the Error function from the desired frequency response
+ * on the dense grid (D[]), the weight function on the dense grid (W[]),
+ * and the present response calculation (A[])
+ *
+ *
+ * INPUT:
+ * ------
+ * int r - 1/2 the number of filter coefficients
+ * double ad[] - [r+1]
+ * double x[] - [r+1]
+ * double y[] - [r+1]
+ * int gridsize - Number of elements in the dense frequency grid
+ * double Grid[] - Frequencies on the dense grid [gridsize]
+ * double D[] - Desired response on the dense grid [gridsize]
+ * double W[] - Weight function on the desnse grid [gridsize]
+ *
+ * OUTPUT:
+ * -------
+ * double E[] - Error function on dense grid [gridsize]
+ ************************/
+
+static void
+CalcError (int r, double ad[], double x[], double y[],
+ int gridsize, double Grid[],
+ double D[], double W[], double E[])
+{
+ int i;
+ double A;
+
+ for (i=0; i<gridsize; i++)
+ {
+ A = ComputeA(Grid[i], r, ad, x, y);
+ E[i] = W[i] * (D[i] - A);
+ }
+}
+
+/************************
+ * Search
+ *========
+ * Searches for the maxima/minima of the error curve. If more than
+ * r+1 extrema are found, it uses the following heuristic (thanks
+ * Chris Hanson):
+ * 1) Adjacent non-alternating extrema deleted first.
+ * 2) If there are more than one excess extrema, delete the
+ * one with the smallest error. This will create a non-alternation
+ * condition that is fixed by 1).
+ * 3) If there is exactly one excess extremum, delete the smaller
+ * of the first/last extremum
+ *
+ *
+ * INPUT:
+ * ------
+ * int r - 1/2 the number of filter coefficients
+ * int Ext[] - Indexes to Grid[] of extremal frequencies [r+1]
+ * int gridsize - Number of elements in the dense frequency grid
+ * double E[] - Array of error values. [gridsize]
+ * OUTPUT:
+ * -------
+ * int Ext[] - New indexes to extremal frequencies [r+1]
+ ************************/
+static int
+Search (int r, int Ext[],
+ int gridsize, double E[])
+{
+ int i, j, k, l, extra; /* Counters */
+ int up, alt;
+ int *foundExt; /* Array of found extremals */
+
+/*
+ * Allocate enough space for found extremals.
+ */
+ foundExt = (int *)malloc((2*r) * sizeof(int));
+ k = 0;
+
+/*
+ * Check for extremum at 0.
+ */
+ if (((E[0]>0.0) && (E[0]>E[1])) ||
+ ((E[0]<0.0) && (E[0]<E[1])))
+ foundExt[k++] = 0;
+
+/*
+ * Check for extrema inside dense grid
+ */
+ for (i=1; i<gridsize-1; i++)
+ {
+ if (((E[i]>=E[i-1]) && (E[i]>E[i+1]) && (E[i]>0.0)) ||
+ ((E[i]<=E[i-1]) && (E[i]<E[i+1]) && (E[i]<0.0))) {
+ // PAK: we sometimes get too many extremal frequencies
+ if (k >= 2*r) return -3;
+ foundExt[k++] = i;
+ }
+ }
+
+/*
+ * Check for extremum at 0.5
+ */
+ j = gridsize-1;
+ if (((E[j]>0.0) && (E[j]>E[j-1])) ||
+ ((E[j]<0.0) && (E[j]<E[j-1]))) {
+ if (k >= 2*r) return -3;
+ foundExt[k++] = j;
+ }
+
+ // PAK: we sometimes get not enough extremal frequencies
+ if (k < r+1) return -2;
+
+
+/*
+ * Remove extra extremals
+ */
+ extra = k - (r+1);
+ assert(extra >= 0);
+
+ while (extra > 0)
+ {
+ if (E[foundExt[0]] > 0.0)
+ up = 1; /* first one is a maxima */
+ else
+ up = 0; /* first one is a minima */
+
+ l=0;
+ alt = 1;
+ for (j=1; j<k; j++)
+ {
+ if (fabs(E[foundExt[j]]) < fabs(E[foundExt[l]]))
+ l = j; /* new smallest error. */
+ if ((up) && (E[foundExt[j]] < 0.0))
+ up = 0; /* switch to a minima */
+ else if ((!up) && (E[foundExt[j]] > 0.0))
+ up = 1; /* switch to a maxima */
+ else
+ {
+ alt = 0;
+ // PAK: break now and you will delete the smallest overall
+ // extremal. If you want to delete the smallest of the
+ // pair of non-alternating extremals, then you must do:
+ //
+ // if (fabs(E[foundExt[j]]) < fabs(E[foundExt[j-1]])) l=j;
+ // else l=j-1;
+ break; /* Ooops, found two non-alternating */
+ } /* extrema. Delete smallest of them */
+ } /* if the loop finishes, all extrema are alternating */
+
+/*
+ * If there's only one extremal and all are alternating,
+ * delete the smallest of the first/last extremals.
+ */
+ if ((alt) && (extra == 1))
+ {
+ if (fabs(E[foundExt[k-1]]) < fabs(E[foundExt[0]]))
+ /* Delete last extremal */
+ l = k-1;
+ // PAK: changed from l = foundExt[k-1];
+ else
+ /* Delete first extremal */
+ l = 0;
+ // PAK: changed from l = foundExt[0];
+ }
+
+ for (j=l; j<k-1; j++) /* Loop that does the deletion */
+ {
+ foundExt[j] = foundExt[j+1];
+ assert(foundExt[j]<gridsize);
+ }
+ k--;
+ extra--;
+ }
+
+ for (i=0; i<=r; i++)
+ {
+ assert(foundExt[i]<gridsize);
+ Ext[i] = foundExt[i]; /* Copy found extremals to Ext[] */
+ }
+
+ free(foundExt);
+ return 0;
+}
+
+
+/*********************
+ * FreqSample
+ *============
+ * Simple frequency sampling algorithm to determine the impulse
+ * response h[] from A's found in ComputeA
+ *
+ *
+ * INPUT:
+ * ------
+ * int N - Number of filter coefficients
+ * double A[] - Sample points of desired response [N/2]
+ * int symmetry - Symmetry of desired filter
+ *
+ * OUTPUT:
+ * -------
+ * double h[] - Impulse Response of final filter [N]
+ *********************/
+static void
+FreqSample (int N, double A[], double h[], int symm)
+{
+ int n, k;
+ double x, val, M;
+
+ M = (N-1.0)/2.0;
+ if (symm == POSITIVE)
+ {
+ if (N%2)
+ {
+ for (n=0; n<N; n++)
+ {
+ val = A[0];
+ x = Pi2 * (n - M)/N;
+ for (k=1; k<=M; k++)
+ val += 2.0 * A[k] * cos(x*k);
+ h[n] = val/N;
+ }
+ }
+ else
+ {
+ for (n=0; n<N; n++)
+ {
+ val = A[0];
+ x = Pi2 * (n - M)/N;
+ for (k=1; k<=(N/2-1); k++)
+ val += 2.0 * A[k] * cos(x*k);
+ h[n] = val/N;
+ }
+ }
+ }
+ else
+ {
+ if (N%2)
+ {
+ for (n=0; n<N; n++)
+ {
+ val = 0;
+ x = Pi2 * (n - M)/N;
+ for (k=1; k<=M; k++)
+ val += 2.0 * A[k] * sin(x*k);
+ h[n] = val/N;
+ }
+ }
+ else
+ {
+ for (n=0; n<N; n++)
+ {
+ val = A[N/2] * sin(Pi * (n - M));
+ x = Pi2 * (n - M)/N;
+ for (k=1; k<=(N/2-1); k++)
+ val += 2.0 * A[k] * sin(x*k);
+ h[n] = val/N;
+ }
+ }
+ }
+}
+
+/*******************
+ * isDone
+ *========
+ * Checks to see if the error function is small enough to consider
+ * the result to have converged.
+ *
+ * INPUT:
+ * ------
+ * int r - 1/2 the number of filter coeffiecients
+ * int Ext[] - Indexes to extremal frequencies [r+1]
+ * double E[] - Error function on the dense grid [gridsize]
+ *
+ * OUTPUT:
+ * -------
+ * Returns 1 if the result converged
+ * Returns 0 if the result has not converged
+ ********************/
+
+static bool
+isDone (int r, int Ext[], double E[])
+{
+ int i;
+ double min, max, current;
+
+ min = max = fabs(E[Ext[0]]);
+ for (i=1; i<=r; i++)
+ {
+ current = fabs(E[Ext[i]]);
+ if (current < min)
+ min = current;
+ if (current > max)
+ max = current;
+ }
+ return (((max-min)/max) < 0.0001);
+}
+
+/********************
+ * remez
+ *=======
+ * Calculates the optimal (in the Chebyshev/minimax sense)
+ * FIR filter impulse response given a set of band edges,
+ * the desired reponse on those bands, and the weight given to
+ * the error in those bands.
+ *
+ * INPUT:
+ * ------
+ * int numtaps - Number of filter coefficients
+ * int numband - Number of bands in filter specification
+ * double bands[] - User-specified band edges [2 * numband]
+ * double des[] - User-specified band responses [2 * numband]
+ * double weight[] - User-specified error weights [numband]
+ * int type - Type of filter
+ *
+ * OUTPUT:
+ * -------
+ * double h[] - Impulse response of final filter [numtaps]
+ * returns - true on success, false on failure to converge
+ ********************/
+
+static int
+remez (double h[], int numtaps,
+ int numband, const double bands[],
+ const double des[], const double weight[],
+ int type, int griddensity)
+{
+ double *Grid, *W, *D, *E;
+ int i, iter, gridsize, r, *Ext;
+ double *taps, c;
+ double *x, *y, *ad;
+ int symmetry;
+
+ if (type == BANDPASS)
+ symmetry = POSITIVE;
+ else
+ symmetry = NEGATIVE;
+
+ r = numtaps/2; /* number of extrema */
+ if ((numtaps%2) && (symmetry == POSITIVE))
+ r++;
+
+/*
+ * Predict dense grid size in advance for memory allocation
+ * .5 is so we round up, not truncate
+ */
+ gridsize = 0;
+ for (i=0; i<numband; i++)
+ {
+ gridsize += (int)(2*r*griddensity*(bands[2*i+1] - bands[2*i]) + .5);
+ }
+ if (symmetry == NEGATIVE)
+ {
+ gridsize--;
+ }
+
+/*
+ * Dynamically allocate memory for arrays with proper sizes
+ */
+ Grid = (double *)malloc(gridsize * sizeof(double));
+ D = (double *)malloc(gridsize * sizeof(double));
+ W = (double *)malloc(gridsize * sizeof(double));
+ E = (double *)malloc(gridsize * sizeof(double));
+ Ext = (int *)malloc((r+1) * sizeof(int));
+ taps = (double *)malloc((r+1) * sizeof(double));
+ x = (double *)malloc((r+1) * sizeof(double));
+ y = (double *)malloc((r+1) * sizeof(double));
+ ad = (double *)malloc((r+1) * sizeof(double));
+
+/*
+ * Create dense frequency grid
+ */
+ CreateDenseGrid(r, numtaps, numband, bands, des, weight,
+ gridsize, Grid, D, W, symmetry, griddensity);
+ InitialGuess(r, Ext, gridsize);
+
+/*
+ * For Differentiator: (fix grid)
+ */
+ if (type == DIFFERENTIATOR)
+ {
+ for (i=0; i<gridsize; i++)
+ {
+/* D[i] = D[i]*Grid[i]; */
+ if (D[i] > 0.0001)
+ W[i] = W[i]/Grid[i];
+ }
+ }
+
+/*
+ * For odd or Negative symmetry filters, alter the
+ * D[] and W[] according to Parks McClellan
+ */
+ if (symmetry == POSITIVE)
+ {
+ if (numtaps % 2 == 0)
+ {
+ for (i=0; i<gridsize; i++)
+ {
+ c = cos(Pi * Grid[i]);
+ D[i] /= c;
+ W[i] *= c;
+ }
+ }
+ }
+ else
+ {
+ if (numtaps % 2)
+ {
+ for (i=0; i<gridsize; i++)
+ {
+ c = sin(Pi2 * Grid[i]);
+ D[i] /= c;
+ W[i] *= c;
+ }
+ }
+ else
+ {
+ for (i=0; i<gridsize; i++)
+ {
+ c = sin(Pi * Grid[i]);
+ D[i] /= c;
+ W[i] *= c;
+ }
+ }
+ }
+
+/*
+ * Perform the Remez Exchange algorithm
+ */
+ for (iter=0; iter<MAXITERATIONS; iter++)
+ {
+ CalcParms(r, Ext, Grid, D, W, ad, x, y);
+ CalcError(r, ad, x, y, gridsize, Grid, D, W, E);
+ int err = Search(r, Ext, gridsize, E);
+ if (err) return err;
+ for(int i=0; i <= r; i++) assert(Ext[i]<gridsize);
+ if (isDone(r, Ext, E))
+ break;
+ }
+
+ CalcParms(r, Ext, Grid, D, W, ad, x, y);
+
+/*
+ * Find the 'taps' of the filter for use with Frequency
+ * Sampling. If odd or Negative symmetry, fix the taps
+ * according to Parks McClellan
+ */
+ for (i=0; i<=numtaps/2; i++)
+ {
+ if (symmetry == POSITIVE)
+ {
+ if (numtaps%2)
+ c = 1;
+ else
+ c = cos(Pi * (double)i/numtaps);
+ }
+ else
+ {
+ if (numtaps%2)
+ c = sin(Pi2 * (double)i/numtaps);
+ else
+ c = sin(Pi * (double)i/numtaps);
+ }
+ taps[i] = ComputeA((double)i/numtaps, r, ad, x, y)*c;
+ }
+
+/*
+ * Frequency sampling design with calculated taps
+ */
+ FreqSample(numtaps, taps, h, symmetry);
+
+/*
+ * Delete allocated memory
+ */
+ free(Grid);
+ free(W);
+ free(D);
+ free(E);
+ free(Ext);
+ free(x);
+ free(y);
+ free(ad);
+ return iter<MAXITERATIONS?0:-1;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// GNU Radio interface
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+static void
+punt (const std::string msg)
+{
+ std::cerr << msg << '\n';
+ throw std::runtime_error (msg);
+}
+
+std::vector<double>
+gr_remez (int order,
+ const std::vector<double> &arg_bands,
+ const std::vector<double> &arg_response,
+ const std::vector<double> &arg_weight,
+ const std::string filter_type,
+ int grid_density
+ ) throw (std::runtime_error)
+{
+ int numtaps = order + 1;
+ if (numtaps < 4)
+ punt ("gr_remez: number of taps must be >= 3");
+
+ int numbands = arg_bands.size () / 2;
+ LOCAL_BUFFER (double, bands, numbands * 2);
+ if (numbands < 1 || arg_bands.size () % 2 == 1)
+ punt ("gr_remez: must have an even number of band edges");
+
+ for (unsigned int i = 1; i < arg_bands.size (); i++){
+ if (arg_bands[i] < arg_bands[i-1])
+ punt ("gr_remez: band edges must be nondecreasing");
+ }
+
+ if (arg_bands[0] < 0 || arg_bands[arg_bands.size () - 1] > 1)
+ punt ("gr_remez: band edges must be in the range [0,1]");
+
+ for (int i = 0; i < 2 * numbands; i++)
+ bands[i] = arg_bands[i] / 2; // FIXME why / 2?
+
+ LOCAL_BUFFER (double, response, numbands * 2);
+ if (arg_response.size () != arg_bands.size ())
+ punt ("gr_remez: must have one response magnitude for each band edge");
+
+ for (int i = 0; i < 2 * numbands; i++)
+ response[i] = arg_response[i];
+
+ LOCAL_BUFFER (double, weight, numbands);
+ for (int i = 0; i < numbands; i++)
+ weight[i] = 1.0;
+
+ if (arg_weight.size () != 0){
+ if ((int) arg_weight.size () != numbands)
+ punt ("gr_remez: need one weight for each band [=length(band)/2]");
+ for (int i = 0; i < numbands; i++)
+ weight[i] = arg_weight [i];
+ }
+
+ int itype = 0;
+ if (filter_type == "bandpass")
+ itype = BANDPASS;
+ else if (filter_type == "differentiator")
+ itype = DIFFERENTIATOR;
+ else if (filter_type == "hilbert")
+ itype = HILBERT;
+ else
+ punt ("gr_remez: unknown ftype '" + filter_type + "'");
+
+ if (grid_density < 16)
+ punt ("gr_remez: grid_density is too low; must be >= 16");
+
+ LOCAL_BUFFER (double, coeff, numtaps + 5); // FIXME why + 5?
+ int err = remez (coeff, numtaps, numbands,
+ bands, response, weight, itype, grid_density);
+
+ if (err == -1)
+ punt ("gr_remez: failed to converge");
+
+ if (err == -2)
+ punt ("gr_remez: insufficient extremals -- cannot continue");
+
+ if (err == -3)
+ punt ("gr_remez: too many extremals -- cannot continue");
+
+ return std::vector<double> (&coeff[0], &coeff[numtaps]);
+}
+
+
+
+#if 0
+/* == Octave interface starts here ====================================== */
+
+DEFUN_DLD (remez, args, ,
+ "b = remez(n, f, a [, w] [, ftype] [, griddensity])\n\
+Parks-McClellan optimal FIR filter design.\n\
+n gives the number of taps in the returned filter\n\
+f gives frequency at the band edges [ b1 e1 b2 e2 b3 e3 ...]\n\
+a gives amplitude at the band edges [ a(b1) a(e1) a(b2) a(e2) ...]\n\
+w gives weighting applied to each band\n\
+ftype is 'bandpass', 'hilbert' or 'differentiator'\n\
+griddensity determines how accurately the filter will be\n\
+ constructed. The minimum value is 16, but higher numbers are\n\
+ slower to compute.\n\
+\n\
+Frequency is in the range (0, 1), with 1 being the nyquist frequency")
+{
+ octave_value_list retval;
+ int i;
+
+ int nargin = args.length();
+ if (nargin < 3 || nargin > 6) {
+ print_usage("remez");
+ return retval;
+ }
+
+ int numtaps = NINT (args(0).double_value()) + 1; // #coeff = filter order+1
+ if (numtaps < 4) {
+ error("remez: number of taps must be an integer greater than 3");
+ return retval;
+ }
+
+ ColumnVector o_bands(args(1).vector_value());
+ int numbands = o_bands.length()/2;
+ OCTAVE_LOCAL_BUFFER(double, bands, numbands*2);
+ if (numbands < 1 || o_bands.length()%2 == 1) {
+ error("remez: must have an even number of band edges");
+ return retval;
+ }
+ for (i=1; i < o_bands.length(); i++) {
+ if (o_bands(i)<o_bands(i-1)) {
+ error("band edges must be nondecreasing");
+ return retval;
+ }
+ }
+ if (o_bands(0) < 0 || o_bands(1) > 1) {
+ error("band edges must be in the range [0,1]");
+ return retval;
+ }
+ for(i=0; i < 2*numbands; i++) bands[i] = o_bands(i)/2.0;
+
+ ColumnVector o_response(args(2).vector_value());
+ OCTAVE_LOCAL_BUFFER (double, response, numbands*2);
+ if (o_response.length() != o_bands.length()) {
+ error("remez: must have one response magnitude for each band edge");
+ return retval;
+ }
+ for(i=0; i < 2*numbands; i++) response[i] = o_response(i);
+
+ std::string stype = std::string("bandpass");
+ int density = 16;
+ OCTAVE_LOCAL_BUFFER (double, weight, numbands);
+ for (i=0; i < numbands; i++) weight[i] = 1.0;
+ if (nargin > 3) {
+ if (args(3).is_real_matrix()) {
+ ColumnVector o_weight(args(3).vector_value());
+ if (o_weight.length() != numbands) {
+ error("remez: need one weight for each band [=length(band)/2]");
+ return retval;
+ }
+ for (i=0; i < numbands; i++) weight[i] = o_weight(i);
+ }
+ else if (args(3).is_string())
+ stype = args(3).string_value();
+ else if (args(3).is_real_scalar())
+ density = NINT(args(3).double_value());
+ else {
+ error("remez: incorrect argument list");
+ return retval;
+ }
+ }
+ if (nargin > 4) {
+ if (args(4).is_string() && !args(3).is_string())
+ stype = args(4).string_value();
+ else if (args(4).is_real_scalar() && !args(3).is_real_scalar())
+ density = NINT(args(4).double_value());
+ else {
+ error("remez: incorrect argument list");
+ return retval;
+ }
+ }
+ if (nargin > 5) {
+ if (args(5).is_real_scalar()
+ && !args(4).is_real_scalar()
+ && !args(3).is_real_scalar())
+ density = NINT(args(4).double_value());
+ else {
+ error("remez: incorrect argument list");
+ return retval;
+ }
+ }
+
+ int itype;
+ if (stype == "bandpass")
+ itype = BANDPASS;
+ else if (stype == "differentiator")
+ itype = DIFFERENTIATOR;
+ else if (stype == "hilbert")
+ itype = HILBERT;
+ else {
+ error("remez: unknown ftype '%s'", stype.data());
+ return retval;
+ }
+
+ if (density < 16) {
+ error("remez: griddensity is too low; must be greater than 16");
+ return retval;
+ }
+
+ OCTAVE_LOCAL_BUFFER (double, coeff, numtaps+5);
+ int err = remez(coeff,numtaps,numbands,bands,response,weight,itype,density);
+
+ if (err == -1)
+ warning("remez: -- failed to converge -- returned filter may be bad.");
+ else if (err == -2) {
+ error("remez: insufficient extremals--cannot continue");
+ return retval;
+ }
+ else if (err == -3) {
+ error("remez: too many extremals--cannot continue");
+ return retval;
+ }
+
+ ColumnVector h(numtaps);
+ while(numtaps--) h(numtaps) = coeff[numtaps];
+
+ return octave_value(h);
+}
+
+/*
+%!test
+%! b = [
+%! 0.0415131831103279
+%! 0.0581639884202646
+%! -0.0281579212691008
+%! -0.0535575358002337
+%! -0.0617245915143180
+%! 0.0507753178978075
+%! 0.2079018331396460
+%! 0.3327160895375440
+%! 0.3327160895375440
+%! 0.2079018331396460
+%! 0.0507753178978075
+%! -0.0617245915143180
+%! -0.0535575358002337
+%! -0.0281579212691008
+%! 0.0581639884202646
+%! 0.0415131831103279];
+%! assert(remez(15,[0,0.3,0.4,1],[1,1,0,0]),b,1e-14);
+
+ */
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_remez.h b/gnuradio-core/src/lib/general/gr_remez.h
new file mode 100644
index 0000000000..c910803bd1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_remez.h
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_REMEZ_H
+#define INCLUDED_GR_REMEZ_H
+
+#include <gr_types.h>
+#include <string>
+#include <stdexcept>
+
+/*!
+ * \brief Parks-McClellan FIR filter design.
+ *
+ *
+ * Calculates the optimal (in the Chebyshev/minimax sense) FIR filter
+ * inpulse reponse given a set of band edges, the desired reponse on
+ * those bands, and the weight given to the error in those bands.
+ *
+ * \param order filter order (number of taps in the returned filter - 1)
+ * \param bands frequency at the band edges [ b1 e1 b2 e2 b3 e3 ...]
+ * \param ampl desired amplitude at the band edges [ a(b1) a(e1) a(b2) a(e2) ...]
+ * \param error_weight weighting applied to each band (usually 1)
+ * \param filter_type one of "bandpass", "hilbert" or "differentiator"
+ * \param grid_density determines how accurately the filter will be constructed. \
+ * The minimum value is 16; higher values are slower to compute.
+ *
+ * Frequency is in the range [0, 1], with 1 being the Nyquist frequency (Fs/2)
+ *
+ * \returns vector of computed taps
+ *
+ * \throws std::runtime_error if args are invalid or calculation fails to converge.
+ */
+
+std::vector<double>
+gr_remez (int order,
+ const std::vector<double> &bands,
+ const std::vector<double> &ampl,
+ const std::vector<double> &error_weight,
+ const std::string filter_type = "bandpass",
+ int grid_density = 16
+ ) throw (std::runtime_error);
+
+
+#endif /* INCLUDED_GR_REMEZ_H */
diff --git a/gnuradio-core/src/lib/general/gr_remez.i b/gnuradio-core/src/lib/general/gr_remez.i
new file mode 100644
index 0000000000..2e2471e2a3
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+%rename(remez) gr_remez;
+
+std::vector<double>
+gr_remez (int order,
+ const std::vector<double> &bands,
+ const std::vector<double> &ampl,
+ const std::vector<double> &error_weight,
+ const std::string filter_type = "bandpass",
+ int grid_density = 16
+ ) throw (std::runtime_error);
diff --git a/gnuradio-core/src/lib/general/gr_reverse.cc b/gnuradio-core/src/lib/general/gr_reverse.cc
new file mode 100644
index 0000000000..099deb6018
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_reverse.h>
+
+
+std::vector<float>
+gr_reverse (const std::vector<float> &taps)
+{
+ int size = taps.size ();
+ std::vector<float> new_taps(size);
+
+ if (size == 0)
+ return new_taps;
+
+ for (int i = 0; i < size; i++)
+ new_taps[i] = taps[size - i - 1];
+
+ return new_taps;
+}
+
+
+std::vector<gr_complex>
+gr_reverse (const std::vector<gr_complex> &taps)
+{
+ int size = taps.size ();
+ std::vector<gr_complex> new_taps(size);
+
+ if (size == 0)
+ return new_taps;
+
+ for (int i = 0; i < size; i++)
+ new_taps[i] = taps[size - i - 1];
+
+ return new_taps;
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_reverse.h b/gnuradio-core/src/lib/general/gr_reverse.h
new file mode 100644
index 0000000000..cff5325591
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_reverse.h
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_REVERSE_H
+#define INCLUDED_GR_REVERSE_H
+
+#include <vector>
+#include <gr_complex.h>
+
+// reverse the order of taps
+std::vector<float> gr_reverse (const std::vector<float> &taps);
+std::vector<gr_complex> gr_reverse (const std::vector<gr_complex> &taps);
+
+
+#endif /* INCLUDED_GR_REVERSE_H */
diff --git a/gnuradio-core/src/lib/general/gr_rms_cf.cc b/gnuradio-core/src/lib/general/gr_rms_cf.cc
new file mode 100644
index 0000000000..7abfefd1d0
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_rms_cf.cc
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_rms_cf.h>
+#include <gr_io_signature.h>
+#include <cmath>
+
+gr_rms_cf_sptr
+gr_make_rms_cf(double alpha)
+{
+ return gr_rms_cf_sptr(new gr_rms_cf(alpha));
+}
+
+gr_rms_cf::gr_rms_cf (double alpha)
+ : gr_sync_block ("rms_cf",
+ gr_make_io_signature(1, 1, sizeof(gr_complex)),
+ gr_make_io_signature(1, 1, sizeof(float))),
+ d_iir(alpha)
+{
+
+}
+
+gr_rms_cf::~gr_rms_cf()
+{
+}
+
+
+int
+gr_rms_cf::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *in = (const gr_complex *) input_items[0];
+ float *out = (float *) output_items[0];
+
+ for (int i = 0; i < noutput_items; i++){
+ double mag_sqrd = in[i].real()*in[i].real() + in[i].imag()*in[i].imag();
+ double f = d_iir.filter(mag_sqrd);
+ out[i] = sqrt(f);
+ }
+
+ return noutput_items;
+}
+
+void
+gr_rms_cf::set_alpha(double alpha)
+{
+ d_iir.set_taps(alpha);
+}
diff --git a/gnuradio-core/src/lib/general/gr_rms_cf.h b/gnuradio-core/src/lib/general/gr_rms_cf.h
new file mode 100644
index 0000000000..bc16c23ed3
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_rms_cf.h
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_RMS_CF_H
+#define INCLUDED_GR_RMS_CF_H
+
+#include <gr_sync_block.h>
+#include <gr_single_pole_iir.h>
+
+class gr_rms_cf;
+typedef boost::shared_ptr<gr_rms_cf> gr_rms_cf_sptr;
+
+gr_rms_cf_sptr
+gr_make_rms_cf (double alpha = 0.0001);
+
+/*!
+ * \brief RMS average power
+ */
+class gr_rms_cf : public gr_sync_block
+{
+ gr_single_pole_iir<double,double,double> d_iir;
+ bool d_unmuted;
+
+ friend gr_rms_cf_sptr
+ gr_make_rms_cf (double alpha);
+
+ gr_rms_cf (double alpha);
+
+public:
+ ~gr_rms_cf ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ bool unmuted () const { return d_unmuted; }
+
+ void set_alpha (double alpha);
+};
+
+#endif /* INCLUDED_GR_RMS_CF_H */
diff --git a/gnuradio-core/src/lib/general/gr_rms_cf.i b/gnuradio-core/src/lib/general/gr_rms_cf.i
new file mode 100644
index 0000000000..0d7b05c8ae
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,rms_cf);
+
+gr_rms_cf_sptr
+gr_make_rms_cf (double alpha = 0.0001);
+
+class gr_rms_cf : public gr_sync_block
+{
+public:
+ bool unmuted () const { return d_unmuted; }
+ void set_alpha (double alpha);
+};
diff --git a/gnuradio-core/src/lib/general/gr_rms_ff.cc b/gnuradio-core/src/lib/general/gr_rms_ff.cc
new file mode 100644
index 0000000000..187be638e6
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_rms_ff.cc
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_rms_ff.h>
+#include <gr_io_signature.h>
+#include <cmath>
+
+gr_rms_ff_sptr
+gr_make_rms_ff(double alpha)
+{
+ return gr_rms_ff_sptr(new gr_rms_ff(alpha));
+}
+
+gr_rms_ff::gr_rms_ff (double alpha)
+ : gr_sync_block ("rms_ff",
+ gr_make_io_signature(1, 1, sizeof(float)),
+ gr_make_io_signature(1, 1, sizeof(float))),
+ d_iir(alpha)
+{
+
+}
+
+gr_rms_ff::~gr_rms_ff()
+{
+}
+
+
+int
+gr_rms_ff::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+ float *out = (float *) output_items[0];
+
+ for (int i = 0; i < noutput_items; i++){
+ double mag_sqrd = in[i]*in[i];
+ double f = d_iir.filter(mag_sqrd);
+ out[i] = sqrt(f);
+ }
+
+ return noutput_items;
+}
+
+void
+gr_rms_ff::set_alpha(double alpha)
+{
+ d_iir.set_taps(alpha);
+}
diff --git a/gnuradio-core/src/lib/general/gr_rms_ff.h b/gnuradio-core/src/lib/general/gr_rms_ff.h
new file mode 100644
index 0000000000..3f276eb216
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_rms_ff.h
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_RMS_FF_H
+#define INCLUDED_GR_RMS_FF_H
+
+#include <gr_sync_block.h>
+#include <gr_single_pole_iir.h>
+
+class gr_rms_ff;
+typedef boost::shared_ptr<gr_rms_ff> gr_rms_ff_sptr;
+
+gr_rms_ff_sptr
+gr_make_rms_ff (double alpha = 0.0001);
+
+/*!
+ * \brief RMS average power
+ */
+class gr_rms_ff : public gr_sync_block
+{
+ gr_single_pole_iir<double,double,double> d_iir;
+ bool d_unmuted;
+
+ friend gr_rms_ff_sptr
+ gr_make_rms_ff (double alpha);
+
+ gr_rms_ff (double alpha);
+
+public:
+ ~gr_rms_ff ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ bool unmuted () const { return d_unmuted; }
+
+ void set_alpha (double alpha);
+};
+
+#endif /* INCLUDED_GR_RMS_FF_H */
diff --git a/gnuradio-core/src/lib/general/gr_rms_ff.i b/gnuradio-core/src/lib/general/gr_rms_ff.i
new file mode 100644
index 0000000000..bf9dbe2dfa
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,rms_ff);
+
+gr_rms_ff_sptr
+gr_make_rms_ff (double alpha = 0.0001);
+
+class gr_rms_ff : public gr_sync_block
+{
+public:
+ bool unmuted () const { return d_unmuted; }
+ void set_alpha (double alpha);
+};
diff --git a/gnuradio-core/src/lib/general/gr_short_to_float.cc b/gnuradio-core/src/lib/general/gr_short_to_float.cc
new file mode 100644
index 0000000000..3ca7937334
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_short_to_float.cc
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_short_to_float.h>
+#include <gr_io_signature.h>
+#include <gri_short_to_float.h>
+
+gr_short_to_float_sptr
+gr_make_short_to_float ()
+{
+ return gr_short_to_float_sptr (new gr_short_to_float ());
+}
+
+gr_short_to_float::gr_short_to_float ()
+ : gr_sync_block ("gr_short_to_float",
+ gr_make_io_signature (1, 1, sizeof (short)),
+ gr_make_io_signature (1, 1, sizeof (float)))
+{
+}
+
+int
+gr_short_to_float::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const short *in = (const short *) input_items[0];
+ float *out = (float *) output_items[0];
+
+ gri_short_to_float (in, out, noutput_items);
+
+ return noutput_items;
+}
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_short_to_float.h b/gnuradio-core/src/lib/general/gr_short_to_float.h
new file mode 100644
index 0000000000..ee5a4ee1cb
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_short_to_float.h
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_SHORT_TO_FLOAT_H
+#define INCLUDED_GR_SHORT_TO_FLOAT_H
+
+#include <gr_sync_block.h>
+
+class gr_short_to_float;
+typedef boost::shared_ptr<gr_short_to_float> gr_short_to_float_sptr;
+
+gr_short_to_float_sptr
+gr_make_short_to_float ();
+
+/*!
+ * \brief Convert stream of short to a stream of float
+ * \ingroup converter
+ */
+
+class gr_short_to_float : public gr_sync_block
+{
+ friend gr_short_to_float_sptr gr_make_short_to_float ();
+ gr_short_to_float ();
+
+ public:
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_SHORT_TO_FLOAT_H */
diff --git a/gnuradio-core/src/lib/general/gr_short_to_float.i b/gnuradio-core/src/lib/general/gr_short_to_float.i
new file mode 100644
index 0000000000..724165d5e9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_short_to_float.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,short_to_float)
+
+gr_short_to_float_sptr gr_make_short_to_float ();
+
+class gr_short_to_float : public gr_sync_block
+{
+ gr_short_to_float ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_sig_source_X.cc.t b/gnuradio-core/src/lib/general/gr_sig_source_X.cc.t
new file mode 100644
index 0000000000..079864b253
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_sig_source_X.cc.t
@@ -0,0 +1,149 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <@NAME@.h>
+#include <algorithm>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <gr_complex.h>
+
+
+@NAME@::@NAME@ (double sampling_freq, gr_waveform_t waveform,
+ double frequency, double ampl, @TYPE@ offset)
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (0, 0, 0),
+ gr_make_io_signature (1, 1, sizeof (@TYPE@))),
+ d_sampling_freq (sampling_freq), d_waveform (waveform), d_frequency (frequency),
+ d_ampl (ampl), d_offset (offset)
+{
+ d_nco.set_freq (2 * M_PI * d_frequency / d_sampling_freq);
+}
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (double sampling_freq, gr_waveform_t waveform,
+ double frequency, double ampl, @TYPE@ offset)
+{
+ return @NAME@_sptr (new @NAME@ (sampling_freq, waveform, frequency, ampl, offset));
+}
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ @TYPE@ *optr = (@TYPE@ *) output_items[0];
+ @TYPE@ t;
+
+ switch (d_waveform){
+
+#if @IS_COMPLEX@ // complex?
+
+ case GR_CONST_WAVE:
+ t = (gr_complex) d_ampl + d_offset;
+ for (int i = 0; i < noutput_items; i++) // FIXME unroll
+ optr[i] = t;
+ break;
+
+ case GR_SIN_WAVE:
+ case GR_COS_WAVE:
+ d_nco.sincos (optr, noutput_items, d_ampl);
+ if (d_offset == gr_complex(0,0))
+ break;
+
+ for (int i = 0; i < noutput_items; i++){
+ optr[i] += d_offset;
+ }
+ break;
+
+#else // nope...
+
+ case GR_CONST_WAVE:
+ t = (@TYPE@) d_ampl + d_offset;
+ for (int i = 0; i < noutput_items; i++) // FIXME unroll
+ optr[i] = t;
+ break;
+
+ case GR_SIN_WAVE:
+ d_nco.sin (optr, noutput_items, d_ampl);
+ if (d_offset == 0)
+ break;
+
+ for (int i = 0; i < noutput_items; i++){
+ optr[i] += d_offset;
+ }
+ break;
+
+ case GR_COS_WAVE:
+ d_nco.cos (optr, noutput_items, d_ampl);
+ if (d_offset == 0)
+ break;
+
+ for (int i = 0; i < noutput_items; i++){
+ optr[i] += d_offset;
+ }
+ break;
+#endif
+
+ default:
+ throw std::runtime_error ("gr_sig_source: invalid waveform");
+ }
+
+ return noutput_items;
+}
+
+void
+@NAME@::set_sampling_freq (double sampling_freq)
+{
+ d_sampling_freq = sampling_freq;
+ d_nco.set_freq (2 * M_PI * d_frequency / d_sampling_freq);
+}
+
+void
+@NAME@::set_waveform (gr_waveform_t waveform)
+{
+ d_waveform = waveform;
+}
+
+void
+@NAME@::set_frequency (double frequency)
+{
+ d_frequency = frequency;
+ d_nco.set_freq (2 * M_PI * d_frequency / d_sampling_freq);
+}
+
+void
+@NAME@::set_amplitude (double ampl)
+{
+ d_ampl = ampl;
+}
+
+void
+@NAME@::set_offset (@TYPE@ offset)
+{
+ d_offset = offset;
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_sig_source_X.h.t b/gnuradio-core/src/lib/general/gr_sig_source_X.h.t
new file mode 100644
index 0000000000..2cdeb32621
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_sig_source_X.h.t
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+#include <gr_sig_source_waveform.h>
+#include <gr_fxpt_nco.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @NAME@_sptr;
+
+/*!
+ * \brief signal generator with @TYPE@ output.
+ * \ingroup source
+ */
+
+class @NAME@ : public gr_sync_block {
+ friend @NAME@_sptr
+ gr_make_@BASE_NAME@ (double sampling_freq, gr_waveform_t waveform,
+ double frequency, double ampl, @TYPE@ offset);
+
+ double d_sampling_freq;
+ gr_waveform_t d_waveform;
+ double d_frequency;
+ double d_ampl;
+ @TYPE@ d_offset;
+ gr_fxpt_nco d_nco;
+
+
+ @NAME@ (double sampling_freq, gr_waveform_t waveform,
+ double wave_freq, double ampl, @TYPE@ offset);
+
+ public:
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ // ACCESSORS
+ double sampling_freq () const { return d_sampling_freq; }
+ gr_waveform_t waveform () const { return d_waveform; }
+ double frequency () const { return d_frequency; }
+ double amplitude () const { return d_ampl; }
+ @TYPE@ offset () const { return d_offset; }
+
+ // MANIPULATORS
+ void set_sampling_freq (double sampling_freq);
+ void set_waveform (gr_waveform_t waveform);
+ void set_frequency (double frequency);
+ void set_amplitude (double ampl);
+ void set_offset (@TYPE@ offset);
+};
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (double sampling_freq, gr_waveform_t waveform,
+ double wave_freq, double ampl, @TYPE@ offset = 0);
+
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_sig_source_X.i.t b/gnuradio-core/src/lib/general/gr_sig_source_X.i.t
new file mode 100644
index 0000000000..3e769d4216
--- /dev/null
+++ b/gnuradio-core/src/lib/general/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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (double sampling_freq, gr_waveform_t waveform,
+ double wave_freq, double ampl, @TYPE@ offset = 0);
+
+
+class @NAME@ : public gr_sync_block {
+ private:
+ @NAME@ (double sampling_freq, gr_waveform_t waveform,
+ double wave_freq, double ampl, @TYPE@ offset);
+
+ public:
+
+ // ACCESSORS
+ double sampling_freq () const { return d_sampling_freq; }
+ gr_waveform_t waveform () const { return d_waveform; }
+ double frequency () const { return d_frequency; }
+ double amplitude () const { return d_ampl; }
+ @TYPE@ offset () const { return d_offset; }
+
+ // MANIPULATORS
+ void set_sampling_freq (double sampling_freq);
+ void set_waveform (gr_waveform_t waveform);
+ void set_frequency (double frequency);
+ void set_amplitude (double ampl);
+ void set_offset (@TYPE@ offset);
+};
diff --git a/gnuradio-core/src/lib/general/gr_sig_source_waveform.h b/gnuradio-core/src/lib/general/gr_sig_source_waveform.h
new file mode 100644
index 0000000000..2d0dc56722
--- /dev/null
+++ b/gnuradio-core/src/lib/general/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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_SIG_SOURCE_WAVEFORM_H
+#define INCLUDED_GR_SIG_SOURCE_WAVEFORM_H
+
+typedef enum {
+ GR_CONST_WAVE = 100, GR_SIN_WAVE, GR_COS_WAVE
+} gr_waveform_t;
+
+#endif /* INCLUDED_GR_SIG_SOURCE_WAVEFORM_H */
diff --git a/gnuradio-core/src/lib/general/gr_simple_correlator.cc b/gnuradio-core/src/lib/general/gr_simple_correlator.cc
new file mode 100644
index 0000000000..09c812391e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_simple_correlator.cc
@@ -0,0 +1,230 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_simple_correlator.h>
+#include <gr_simple_framer_sync.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <stdexcept>
+#include <gr_count_bits.h>
+
+
+static const int THRESHOLD = 3;
+
+gr_simple_correlator_sptr
+gr_make_simple_correlator (int payload_bytesize)
+{
+ return gr_simple_correlator_sptr (new gr_simple_correlator (payload_bytesize));
+}
+
+gr_simple_correlator::gr_simple_correlator (int payload_bytesize)
+ : gr_block ("simple_correlator",
+ gr_make_io_signature (1, 1, sizeof (float)),
+ gr_make_io_signature (1, 1, sizeof (unsigned char))),
+ d_payload_bytesize (payload_bytesize),
+ d_state (ST_LOOKING), d_osi (0),
+ d_bblen ((payload_bytesize + GRSF_PAYLOAD_OVERHEAD) * GRSF_BITS_PER_BYTE),
+ d_bitbuf (new unsigned char [d_bblen]),
+ d_bbi (0)
+{
+ d_avbi = 0;
+ d_accum = 0.0;
+ d_avg = 0.0;
+ for (int i = 0; i < AVG_PERIOD; i++)
+ d_avgbuf[i] = 0.0;
+
+#ifdef DEBUG_SIMPLE_CORRELATOR
+ d_debug_fp = fopen("corr.log", "w");
+#endif
+ enter_looking ();
+
+}
+
+gr_simple_correlator::~gr_simple_correlator ()
+{
+#ifdef DEBUG_SIMPLE_CORRELATOR
+ fclose(d_debug_fp);
+#endif
+ delete [] d_bitbuf;
+}
+
+
+void
+gr_simple_correlator::enter_looking ()
+{
+ fflush (stdout);
+ // fprintf (stderr, ">>> enter_looking\n");
+ d_state = ST_LOOKING;
+ for (int i = 0; i < OVERSAMPLE; i++)
+ d_shift_reg[i] = 0;
+ d_osi = 0;
+
+ d_avbi = 0;
+ d_avg = d_avg * 0.5;
+ d_accum = 0;
+ for (int i = 0; i < AVG_PERIOD; i++)
+ d_avgbuf[i] = 0.0;
+}
+
+void
+gr_simple_correlator::enter_under_threshold ()
+{
+ fflush (stdout);
+ // fprintf (stderr, ">>> enter_under_threshold\n");
+ d_state = ST_UNDER_THRESHOLD;
+ d_transition_osi = d_osi;
+}
+
+void
+gr_simple_correlator::enter_locked ()
+{
+ d_state = ST_LOCKED;
+ int delta = sub_index (d_osi, d_transition_osi);
+ d_center_osi = add_index (d_transition_osi, delta/2);
+ d_center_osi = add_index (d_center_osi, 3); // FIXME
+ d_bbi = 0;
+ fflush (stdout);
+ // fprintf (stderr, ">>> enter_locked d_center_osi = %d\n", d_center_osi);
+
+ d_avg = std::max(-1.0, std::min(1.0, d_accum * (1.0/AVG_PERIOD)));
+ // fprintf(stderr, ">>> enter_locked d_avg = %g\n", d_avg);
+}
+
+static void
+packit (unsigned char *pktbuf, const unsigned char *bitbuf, int bitcount)
+{
+ for (int i = 0; i < bitcount; i += 8){
+ int t = bitbuf[i+0] & 0x1;
+ t = (t << 1) | (bitbuf[i+1] & 0x1);
+ t = (t << 1) | (bitbuf[i+2] & 0x1);
+ t = (t << 1) | (bitbuf[i+3] & 0x1);
+ t = (t << 1) | (bitbuf[i+4] & 0x1);
+ t = (t << 1) | (bitbuf[i+5] & 0x1);
+ t = (t << 1) | (bitbuf[i+6] & 0x1);
+ t = (t << 1) | (bitbuf[i+7] & 0x1);
+ *pktbuf++ = t;
+ }
+}
+
+void
+gr_simple_correlator::update_avg(float x)
+{
+ d_accum -= d_avgbuf[d_avbi];
+ d_avgbuf[d_avbi] = x;
+ d_accum += x;
+ d_avbi = (d_avbi + 1) & (AVG_PERIOD-1);
+}
+
+
+int
+gr_simple_correlator::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+
+
+ int n = 0;
+ int nin = ninput_items[0];
+ int decision;
+ int hamming_dist;
+
+ struct debug_data {
+ float raw_data;
+ float sampled;
+ float enter_locked;
+ } debug_data;
+
+ while (n < nin){
+
+#ifdef DEBUG_SIMPLE_CORRELATOR
+ debug_data.raw_data = in[n];
+ debug_data.sampled = 0.0;
+ debug_data.enter_locked = 0.0;
+#endif
+
+ switch (d_state){
+
+ case ST_LOCKED:
+ if (d_osi == d_center_osi){
+
+#ifdef DEBUG_SIMPLE_CORRELATOR
+ debug_data.sampled = 1.0;
+#endif
+ decision = slice (in[n]);
+
+ d_bitbuf[d_bbi] = decision;
+ d_bbi++;
+ if (d_bbi >= d_bblen){
+ // printf ("got whole packet\n");
+ unsigned char pktbuf[d_bblen/GRSF_BITS_PER_BYTE];
+ packit (pktbuf, d_bitbuf, d_bbi);
+ printf ("seqno %3d\n", pktbuf[0]);
+ memcpy (out, &pktbuf[GRSF_PAYLOAD_OVERHEAD], d_payload_bytesize);
+ enter_looking ();
+ consume_each (n + 1);
+ return d_payload_bytesize;
+ }
+ }
+ break;
+
+ case ST_LOOKING:
+ case ST_UNDER_THRESHOLD:
+ update_avg(in[n]);
+ decision = slice (in[n]);
+ d_shift_reg[d_osi] = (d_shift_reg[d_osi] << 1) | decision;
+
+ hamming_dist = gr_count_bits64 (d_shift_reg[d_osi] ^ GRSF_SYNC);
+ // printf ("%2d %d\n", hamming_dist, d_osi);
+
+ if (d_state == ST_LOOKING && hamming_dist <= THRESHOLD){
+ // We're seeing a good PN code, remember location
+ enter_under_threshold ();
+ }
+ else if (d_state == ST_UNDER_THRESHOLD && hamming_dist > THRESHOLD){
+ // no longer seeing good PN code, compute center of goodness
+ enter_locked ();
+ debug_data.enter_locked = 1.0;
+ }
+ break;
+
+ default:
+ assert (0);
+ }
+
+#ifdef DEBUG_SIMPLE_CORRELATOR
+ fwrite(&debug_data, sizeof (debug_data), 1, d_debug_fp);
+#endif
+
+ d_osi = add_index (d_osi, 1);
+ n++;
+ }
+
+ consume_each (n);
+ return 0;
+}
diff --git a/gnuradio-core/src/lib/general/gr_simple_correlator.h b/gnuradio-core/src/lib/general/gr_simple_correlator.h
new file mode 100644
index 0000000000..5697e170af
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_simple_correlator.h
@@ -0,0 +1,109 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_SIMPLE_CORRELATOR_H
+#define INCLUDED_GR_SIMPLE_CORRELATOR_H
+
+#include <gr_block.h>
+#include <assert.h>
+
+//#define DEBUG_SIMPLE_CORRELATOR
+
+class gr_simple_correlator;
+typedef boost::shared_ptr<gr_simple_correlator> gr_simple_correlator_sptr;
+
+gr_simple_correlator_sptr gr_make_simple_correlator (int payload_bytesize);
+
+/*!
+ * \brief inverse of gr_simple_framer (more or less)
+ * \ingroup block
+ */
+class gr_simple_correlator : public gr_block
+{
+ static const int OVERSAMPLE = 8;
+ enum state_t { ST_LOOKING, ST_UNDER_THRESHOLD, ST_LOCKED };
+
+ int d_payload_bytesize;
+ state_t d_state;
+ unsigned int d_osi; // over sample index [0,OVERSAMPLE-1]
+ unsigned int d_transition_osi; // first index where Hamming dist < thresh
+ unsigned int d_center_osi; // center of bit
+ unsigned long long int d_shift_reg[OVERSAMPLE];
+ int d_bblen; // length of bitbuf
+ unsigned char *d_bitbuf; // demodulated bits
+ int d_bbi; // bitbuf index
+
+ static const int AVG_PERIOD = 512; // must be power of 2 (for freq offset correction)
+ int d_avbi;
+ float d_avgbuf[AVG_PERIOD];
+ float d_avg;
+ float d_accum;
+
+#ifdef DEBUG_SIMPLE_CORRELATOR
+ FILE *d_debug_fp; // binary log file
+#endif
+
+ friend gr_simple_correlator_sptr gr_make_simple_correlator (int payload_bytesize);
+ gr_simple_correlator (int payload_bytesize);
+
+
+ inline int slice (float x)
+ {
+ return x >= d_avg ? 1 : 0;
+ }
+
+ void update_avg(float x);
+
+ void enter_locked ();
+ void enter_under_threshold ();
+ void enter_looking ();
+
+ static int add_index (int a, int b)
+ {
+ int t = a + b;
+ if (t >= OVERSAMPLE)
+ t -= OVERSAMPLE;
+ assert (t >= 0 && t < OVERSAMPLE);
+ return t;
+ }
+
+ static int sub_index (int a, int b)
+ {
+ int t = a - b;
+ if (t < 0)
+ t += OVERSAMPLE;
+ assert (t >= 0 && t < OVERSAMPLE);
+ return t;
+ }
+
+
+ public:
+ ~gr_simple_correlator ();
+
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_SIMPLE_CORRELATOR_H */
diff --git a/gnuradio-core/src/lib/general/gr_simple_correlator.i b/gnuradio-core/src/lib/general/gr_simple_correlator.i
new file mode 100644
index 0000000000..d143648f6c
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,simple_correlator);
+
+gr_simple_correlator_sptr gr_make_simple_correlator (int payload_bytesize);
+
+class gr_simple_correlator : public gr_block
+{
+ private:
+ gr_simple_correlator (int payload_bytesize);
+};
diff --git a/gnuradio-core/src/lib/general/gr_simple_framer.cc b/gnuradio-core/src/lib/general/gr_simple_framer.cc
new file mode 100644
index 0000000000..797b1f3ba3
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_simple_framer.cc
@@ -0,0 +1,100 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_simple_framer.h>
+#include <gr_simple_framer_sync.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <stdexcept>
+
+
+gr_simple_framer_sptr
+gr_make_simple_framer (int payload_bytesize)
+{
+ return gr_simple_framer_sptr (new gr_simple_framer (payload_bytesize));
+}
+
+gr_simple_framer::gr_simple_framer (int payload_bytesize)
+ : gr_block ("simple_framer",
+ gr_make_io_signature (1, 1, sizeof (unsigned char)),
+ gr_make_io_signature (1, 1, sizeof (unsigned char))),
+ d_seqno (0), d_payload_bytesize (payload_bytesize),
+ d_input_block_size (payload_bytesize),
+ d_output_block_size (payload_bytesize + GRSF_OVERHEAD)
+{
+ set_output_multiple (d_output_block_size);
+}
+
+void
+gr_simple_framer::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+ assert (noutput_items % d_output_block_size == 0);
+
+ int nblocks = noutput_items / d_output_block_size;
+ int input_required = nblocks * d_input_block_size;
+
+ unsigned ninputs = ninput_items_required.size();
+ for (unsigned int i = 0; i < ninputs; i++)
+ ninput_items_required[i] = input_required;
+}
+
+int
+gr_simple_framer::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+
+ int n = 0;
+ int nblocks = 0;
+
+ memset (out, 0x55, noutput_items);
+
+ while (n < noutput_items){
+ out[0] = (GRSF_SYNC >> 56) & 0xff;
+ out[1] = (GRSF_SYNC >> 48) & 0xff;
+ out[2] = (GRSF_SYNC >> 40) & 0xff;
+ out[3] = (GRSF_SYNC >> 32) & 0xff;
+ out[4] = (GRSF_SYNC >> 24) & 0xff;
+ out[5] = (GRSF_SYNC >> 16) & 0xff;
+ out[6] = (GRSF_SYNC >> 8) & 0xff;
+ out[7] = (GRSF_SYNC >> 0) & 0xff;
+ out[8] = d_seqno++;
+
+ memcpy (&out[9], in, d_input_block_size);
+ in += d_input_block_size;
+ out += d_output_block_size;
+ n += d_output_block_size;
+ nblocks++;
+ }
+
+ assert (n == noutput_items);
+
+ consume_each (nblocks * d_input_block_size);
+ return n;
+}
diff --git a/gnuradio-core/src/lib/general/gr_simple_framer.h b/gnuradio-core/src/lib/general/gr_simple_framer.h
new file mode 100644
index 0000000000..33813741bb
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_simple_framer.h
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_SIMPLE_FRAMER_H
+#define INCLUDED_GR_SIMPLE_FRAMER_H
+
+#include <gr_block.h>
+
+class gr_simple_framer;
+typedef boost::shared_ptr<gr_simple_framer> gr_simple_framer_sptr;
+
+gr_simple_framer_sptr gr_make_simple_framer (int payload_bytesize);
+
+/*!
+ * \brief add sync field, seq number and command field to payload
+ * \ingroup block
+ */
+class gr_simple_framer : public gr_block
+{
+ int d_seqno;
+ int d_payload_bytesize;
+ int d_input_block_size; // bytes
+ int d_output_block_size; // bytes
+
+ friend gr_simple_framer_sptr gr_make_simple_framer (int payload_bytesize);
+ gr_simple_framer (int payload_bytesize);
+
+ public:
+ void forecast (int noutput_items,
+ gr_vector_int &ninput_items_required);
+
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_SIMPLE_FRAMER_H */
diff --git a/gnuradio-core/src/lib/general/gr_simple_framer.i b/gnuradio-core/src/lib/general/gr_simple_framer.i
new file mode 100644
index 0000000000..4083ce1632
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,simple_framer);
+
+gr_simple_framer_sptr gr_make_simple_framer (int payload_bytesize);
+
+class gr_simple_framer : public gr_block
+{
+ private:
+ gr_simple_framer (int payload_bytesize);
+};
diff --git a/gnuradio-core/src/lib/general/gr_simple_framer_sync.h b/gnuradio-core/src/lib/general/gr_simple_framer_sync.h
new file mode 100644
index 0000000000..c7f65528b0
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_simple_framer_sync.h
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_SIMPLE_FRAMER_SYNC_H
+#define INCLUDED_GR_SIMPLE_FRAMER_SYNC_H
+
+/*
+ * Here are a couple of maximum length sequences (m-sequences) that were generated by the
+ * the "mseq" matlab/octave code downloaded from:
+ * http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=990&objectType=file
+ *
+ * 31-bit m-sequence:
+ * 0110100100001010111011000111110
+ * 0x690AEC76 (padded on right with a zero)
+ *
+ * 63-bit m-sequence:
+ * 101011001101110110100100111000101111001010001100001000001111110
+ * 0xACDDA4E2F28C20FC (padded on right with a zero)
+ */
+
+static const unsigned long long GRSF_SYNC = 0xacdda4e2f28c20fcULL;
+
+static const int GRSF_BITS_PER_BYTE = 8;
+static const int GRSF_SYNC_OVERHEAD = sizeof(GRSF_SYNC);
+static const int GRSF_PAYLOAD_OVERHEAD = 1; // 1 byte seqno
+static const int GRSF_TAIL_PAD = 1; // one byte trailing padding
+static const int GRSF_OVERHEAD = GRSF_SYNC_OVERHEAD + GRSF_PAYLOAD_OVERHEAD + GRSF_TAIL_PAD;
+
+
+#endif /* INCLUDED_GR_SIMPLE_FRAMER_SYNC_H */
diff --git a/gnuradio-core/src/lib/general/gr_simple_squelch_cc.cc b/gnuradio-core/src/lib/general/gr_simple_squelch_cc.cc
new file mode 100644
index 0000000000..e34f9a138d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_simple_squelch_cc.cc
@@ -0,0 +1,99 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_simple_squelch_cc.h>
+#include <gr_io_signature.h>
+#include <cmath>
+
+gr_simple_squelch_cc_sptr
+gr_make_simple_squelch_cc(double threshold_db, double alpha)
+{
+ return gr_simple_squelch_cc_sptr(new gr_simple_squelch_cc(threshold_db, alpha));
+}
+
+gr_simple_squelch_cc::gr_simple_squelch_cc (double threshold_db, double alpha)
+ : gr_sync_block ("simple_squelch_cc",
+ gr_make_io_signature(1, 1, sizeof(gr_complex)),
+ gr_make_io_signature(1, 1, sizeof(gr_complex))),
+ d_iir(alpha), d_unmuted(false)
+{
+ set_threshold (threshold_db);
+}
+
+gr_simple_squelch_cc::~gr_simple_squelch_cc()
+{
+}
+
+
+int
+gr_simple_squelch_cc::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *in = (const gr_complex *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ for (int i = 0; i < noutput_items; i++){
+ double mag_sqrd = in[i].real()*in[i].real() + in[i].imag()*in[i].imag();
+ double f = d_iir.filter(mag_sqrd);
+ if (f >= d_threshold)
+ out[i] = in[i];
+ else
+ out[i] = 0;
+ }
+
+ d_unmuted = d_iir.prev_output() >= d_threshold;
+ return noutput_items;
+}
+
+void
+gr_simple_squelch_cc::set_threshold(double decibels)
+{
+ // convert to absolute threshold (mag squared)
+ d_threshold = std::pow(10.0, decibels/10);
+}
+
+double
+gr_simple_squelch_cc::threshold() const
+{
+ return 10 * log10(d_threshold);
+}
+
+void
+gr_simple_squelch_cc::set_alpha(double alpha)
+{
+ d_iir.set_taps(alpha);
+}
+
+std::vector<float>
+gr_simple_squelch_cc::squelch_range() const
+{
+ std::vector<float> r(3);
+ r[0] = -50.0; // min FIXME
+ r[1] = +50.0; // max FIXME
+ r[2] = (r[1] - r[0]) / 100; // step size
+
+ return r;
+}
diff --git a/gnuradio-core/src/lib/general/gr_simple_squelch_cc.h b/gnuradio-core/src/lib/general/gr_simple_squelch_cc.h
new file mode 100644
index 0000000000..31fde1286d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_simple_squelch_cc.h
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_SIMPLE_SQUELCH_CC_H
+#define INCLUDED_GR_SIMPLE_SQUELCH_CC_H
+
+#include <gr_sync_block.h>
+#include <gr_single_pole_iir.h>
+
+class gr_simple_squelch_cc;
+typedef boost::shared_ptr<gr_simple_squelch_cc> gr_simple_squelch_cc_sptr;
+
+gr_simple_squelch_cc_sptr
+gr_make_simple_squelch_cc (double threshold_db, double alpha = 0.0001);
+
+/*!
+ * \brief simple squelch block based on average signal power and threshold in dB.
+ */
+class gr_simple_squelch_cc : public gr_sync_block
+{
+ double d_threshold;
+ gr_single_pole_iir<double,double,double> d_iir;
+ bool d_unmuted;
+
+ friend gr_simple_squelch_cc_sptr
+ gr_make_simple_squelch_cc (double threshold_db, double alpha);
+
+ gr_simple_squelch_cc (double threshold_db, double alpha);
+
+public:
+ ~gr_simple_squelch_cc ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ bool unmuted () const { return d_unmuted; }
+
+ void set_alpha (double alpha);
+ void set_threshold (double decibels);
+
+ double threshold() const;
+ std::vector<float> squelch_range() const;
+
+};
+
+#endif /* INCLUDED_GR_SIMPLE_SQUELCH_CC_H */
diff --git a/gnuradio-core/src/lib/general/gr_simple_squelch_cc.i b/gnuradio-core/src/lib/general/gr_simple_squelch_cc.i
new file mode 100644
index 0000000000..5e3339a2fa
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,simple_squelch_cc);
+
+gr_simple_squelch_cc_sptr
+gr_make_simple_squelch_cc (double threshold_db, double alpha = 0.0001);
+
+class gr_simple_squelch_cc : public gr_sync_block
+{
+public:
+ bool unmuted () const { return d_unmuted; }
+ void set_alpha (double alpha);
+ void set_threshold (double decibels);
+
+ double threshold() const;
+ std::vector<float> squelch_range() const;
+};
diff --git a/gnuradio-core/src/lib/general/gr_skiphead.cc b/gnuradio-core/src/lib/general/gr_skiphead.cc
new file mode 100644
index 0000000000..599d00bf65
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_skiphead.cc
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_skiphead.h>
+#include <gr_io_signature.h>
+
+gr_skiphead::gr_skiphead (size_t sizeof_stream_item, int nitems)
+ : gr_sync_block ("skiphead",
+ gr_make_io_signature (1, 1, sizeof_stream_item),
+ gr_make_io_signature (1, 1, sizeof_stream_item)),
+ d_nitems (nitems), d_nskipped_items (0)
+{
+}
+
+gr_block_sptr
+gr_make_skiphead (size_t sizeof_stream_item, int nitems)
+{
+ return gr_block_sptr (new gr_skiphead (sizeof_stream_item, nitems));
+}
+
+int
+gr_skiphead::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ int items_to_skip = d_nitems - d_nskipped_items;
+ if (items_to_skip <=0)
+ {
+ //Done with skipping, copy all input to the output;
+ memcpy (output_items[0], input_items[0], noutput_items * input_signature()->sizeof_stream_item (0));
+ return noutput_items;
+ } else if (items_to_skip < noutput_items)
+ {
+ memcpy (output_items[0], &(((char *)input_items[0])[items_to_skip*input_signature()->sizeof_stream_item (0)]), (noutput_items -items_to_skip) * input_signature()->sizeof_stream_item (0));
+ //memcpy (output_items[0], &((input_items[0])[items_to_skip]), (noutput_items -items_to_skip) * input_signature()->sizeof_stream_item (0));
+ //memcpy (output_items[0], input_items[0]+items_to_skip*input_signature()->sizeof_stream_item (0), (noutput_items -items_to_skip) * input_signature()->sizeof_stream_item (0));
+ d_nskipped_items += items_to_skip;
+ consume_each (items_to_skip);
+ return (noutput_items -items_to_skip);
+ } else
+ {
+ d_nskipped_items += noutput_items;
+ consume_each (items_to_skip);
+ return 0;
+ }
+
+ return -1;//Should never get here
+}
diff --git a/gnuradio-core/src/lib/general/gr_skiphead.h b/gnuradio-core/src/lib/general/gr_skiphead.h
new file mode 100644
index 0000000000..e87f8a4ec6
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_skiphead.h
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_SKIPHEAD_H
+#define INCLUDED_GR_SKIPHEAD_H
+
+#include <gr_sync_block.h>
+#include <stddef.h> // size_t
+
+/*!
+ * \brief skips the first N items, from then on copies items to the output
+ * \ingroup block
+ *
+ * Useful for building test cases and sources which have metadata or junk at the start
+ */
+
+class gr_skiphead : public gr_sync_block
+{
+ friend gr_block_sptr gr_make_skiphead (size_t sizeof_stream_item, int nitems);
+ gr_skiphead (size_t sizeof_stream_item, int nitems);
+
+ int d_nitems;
+ int d_nskipped_items;
+
+ public:
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+gr_block_sptr
+gr_make_skiphead (size_t sizeof_stream_item, int nitems);
+
+
+#endif /* INCLUDED_GR_SKIPHEAD_H */
diff --git a/gnuradio-core/src/lib/general/gr_skiphead.i b/gnuradio-core/src/lib/general/gr_skiphead.i
new file mode 100644
index 0000000000..deedeb3be3
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_skiphead.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+%ignore gr_skiphead;
+class gr_skiphead : public gr_block {
+ friend gr_block_sptr gr_make_skiphead (size_t sizeof_stream_item, int nitems);
+ gr_skiphead (size_t sizeof_stream_item, int nitems);
+};
+
+%rename(skiphead) gr_make_skiphead;
+gr_block_sptr gr_make_skiphead (size_t sizeof_stream_item, int nitems);
diff --git a/gnuradio-core/src/lib/general/gr_squelch_base_cc.cc b/gnuradio-core/src/lib/general/gr_squelch_base_cc.cc
new file mode 100644
index 0000000000..b3e61fcc56
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_squelch_base_cc.h>
+#include <gr_io_signature.h>
+
+gr_squelch_base_cc::gr_squelch_base_cc(const char *name, int ramp, bool gate) :
+ gr_block(name,
+ gr_make_io_signature(1, 1, sizeof(gr_complex)),
+ gr_make_io_signature(1, 1, sizeof(gr_complex)))
+{
+ set_ramp(ramp);
+ set_gate(gate);
+ d_state = ST_MUTED;
+ d_envelope = d_ramp ? 0.0 : 1.0;
+ d_ramped = 0;
+}
+
+int gr_squelch_base_cc::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *in = (const gr_complex *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ int j = 0;
+
+ for (int i = 0; i < noutput_items; i++) {
+ update_state(in[i]);
+
+ // Adjust envelope based on current state
+ switch(d_state) {
+ case ST_MUTED:
+ if (!mute())
+ d_state = d_ramp ? ST_ATTACK : ST_UNMUTED; // If not ramping, go straight to unmuted
+ break;
+
+ case ST_UNMUTED:
+ if (mute())
+ d_state = d_ramp ? ST_DECAY : ST_MUTED; // If not ramping, go straight to muted
+ break;
+
+ case ST_ATTACK:
+ d_envelope = 0.5-std::cos(M_PI*(++d_ramped)/d_ramp)/2.0; // FIXME: precalculate window for speed
+ if (d_ramped >= d_ramp) { // use >= in case d_ramp is set to lower value elsewhere
+ d_state = ST_UNMUTED;
+ d_envelope = 1.0;
+ }
+ break;
+
+ case ST_DECAY:
+ d_envelope = 0.5-std::cos(M_PI*(--d_ramped)/d_ramp)/2.0; // FIXME: precalculate window for speed
+ if (d_ramped == 0.0)
+ d_state = ST_MUTED;
+ break;
+ };
+
+ // If unmuted, copy input times envelope to output
+ // Otherwise, if not gating, copy zero to output
+ if (d_state != ST_MUTED)
+ out[j++] = in[i]*gr_complex(d_envelope, 0.0);
+ else
+ if (!d_gate)
+ out[j++] = 0.0;
+ }
+
+ consume_each(noutput_items); // Use all the inputs
+ return j; // But only report outputs copied
+}
diff --git a/gnuradio-core/src/lib/general/gr_squelch_base_cc.h b/gnuradio-core/src/lib/general/gr_squelch_base_cc.h
new file mode 100644
index 0000000000..4e3312844a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_squelch_base_cc.h
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_SQUELCH_BASE_CC_H
+#define INCLUDED_GR_SQUELCH_BASE_CC_H
+
+#include <gr_block.h>
+
+class gr_squelch_base_cc : public gr_block
+{
+private:
+ int d_ramp;
+ int d_ramped;
+ bool d_gate;
+ double d_envelope;
+ enum { ST_MUTED, ST_ATTACK, ST_UNMUTED, ST_DECAY } d_state;
+
+protected:
+ virtual void update_state(const gr_complex &sample) {};
+ virtual bool mute() const { return false; };
+
+public:
+ gr_squelch_base_cc(const char *name, int ramp, bool gate);
+
+ int ramp() const { return d_ramp; }
+ void set_ramp(int ramp) { d_ramp = ramp; }
+ bool gate() const { return d_gate; }
+ void set_gate(bool gate) { d_gate = gate; }
+ bool unmuted() const { return (d_state == ST_UNMUTED || d_state == ST_ATTACK); }
+
+ virtual std::vector<float> squelch_range() const = 0;
+
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_SQUELCH_BASE_CC_H */
diff --git a/gnuradio-core/src/lib/general/gr_squelch_base_cc.i b/gnuradio-core/src/lib/general/gr_squelch_base_cc.i
new file mode 100644
index 0000000000..0ef674c4f7
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gr_block.h>
+
+class gr_squelch_base_cc : public gr_block
+{
+private:
+ enum { ST_MUTED, ST_ATTACK, ST_UNMUTED, ST_DECAY } d_state;
+
+public:
+ gr_squelch_base_cc(const char *name, int ramp, bool gate);
+
+ int ramp() const { return d_ramp; }
+ void set_ramp(int ramp) { d_ramp = ramp; }
+ bool gate() const { return d_gate; }
+ void set_gate(bool gate) { d_gate = gate; }
+ bool unmuted() const { return (d_state == ST_UNMUTED || d_state == ST_ATTACK); }
+
+ virtual std::vector<float> squelch_range() const = 0;
+};
diff --git a/gnuradio-core/src/lib/general/gr_squelch_base_ff.cc b/gnuradio-core/src/lib/general/gr_squelch_base_ff.cc
new file mode 100644
index 0000000000..a457c5f6ca
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_squelch_base_ff.h>
+#include <gr_io_signature.h>
+
+gr_squelch_base_ff::gr_squelch_base_ff(const char *name, int ramp, bool gate) :
+ gr_block(name,
+ gr_make_io_signature(1, 1, sizeof(float)),
+ gr_make_io_signature(1, 1, sizeof(float)))
+{
+ set_ramp(ramp);
+ set_gate(gate);
+ d_state = ST_MUTED;
+ d_envelope = d_ramp ? 0.0 : 1.0;
+ d_ramped = 0;
+}
+
+int gr_squelch_base_ff::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+ float *out = (float *) output_items[0];
+
+ int j = 0;
+
+ for (int i = 0; i < noutput_items; i++) {
+ update_state(in[i]);
+
+ // Adjust envelope based on current state
+ switch(d_state) {
+ case ST_MUTED:
+ if (!mute())
+ d_state = d_ramp ? ST_ATTACK : ST_UNMUTED; // If not ramping, go straight to unmuted
+ break;
+
+ case ST_UNMUTED:
+ if (mute())
+ d_state = d_ramp ? ST_DECAY : ST_MUTED; // If not ramping, go straight to muted
+ break;
+
+ case ST_ATTACK:
+ d_envelope = 0.5-std::cos(M_PI*(++d_ramped)/d_ramp)/2.0; // FIXME: precalculate window for speed
+ if (d_ramped >= d_ramp) { // use >= in case d_ramp is set to lower value elsewhere
+ d_state = ST_UNMUTED;
+ d_envelope = 1.0;
+ }
+ break;
+
+ case ST_DECAY:
+ d_envelope = 0.5-std::cos(M_PI*(--d_ramped)/d_ramp)/2.0; // FIXME: precalculate window for speed
+ if (d_ramped == 0.0)
+ d_state = ST_MUTED;
+ break;
+ };
+
+ // If unmuted, copy input times envelope to output
+ // Otherwise, if not gating, copy zero to output
+ if (d_state != ST_MUTED)
+ out[j++] = in[i]*d_envelope;
+ else
+ if (!d_gate)
+ out[j++] = 0.0;
+ }
+
+ consume_each(noutput_items); // Use all the inputs
+ return j; // But only report outputs copied
+}
diff --git a/gnuradio-core/src/lib/general/gr_squelch_base_ff.h b/gnuradio-core/src/lib/general/gr_squelch_base_ff.h
new file mode 100644
index 0000000000..4128735a7d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_squelch_base_ff.h
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_SQUELCH_BASE_FF_H
+#define INCLUDED_GR_SQUELCH_BASE_FF_H
+
+#include <gr_block.h>
+
+class gr_squelch_base_ff : public gr_block
+{
+private:
+ int d_ramp;
+ int d_ramped;
+ bool d_gate;
+ double d_envelope;
+ enum { ST_MUTED, ST_ATTACK, ST_UNMUTED, ST_DECAY } d_state;
+
+protected:
+ virtual void update_state(const float &sample) {};
+ virtual bool mute() const { return false; };
+
+public:
+ gr_squelch_base_ff(const char *name, int ramp, bool gate);
+
+ int ramp() const { return d_ramp; }
+ void set_ramp(int ramp) { d_ramp = ramp; }
+ bool gate() const { return d_gate; }
+ void set_gate(bool gate) { d_gate = gate; }
+ bool unmuted() const { return (d_state == ST_UNMUTED || d_state == ST_ATTACK); }
+
+ virtual std::vector<float> squelch_range() const = 0;
+
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_SQUELCH_BASE_FF_H */
diff --git a/gnuradio-core/src/lib/general/gr_squelch_base_ff.i b/gnuradio-core/src/lib/general/gr_squelch_base_ff.i
new file mode 100644
index 0000000000..d749d498fb
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gr_block.h>
+
+class gr_squelch_base_ff : public gr_block
+{
+private:
+ enum { ST_MUTED, ST_ATTACK, ST_UNMUTED, ST_DECAY } d_state;
+
+public:
+ gr_squelch_base_ff(const char *name, int ramp, bool gate);
+
+ int ramp() const { return d_ramp; }
+ void set_ramp(int ramp) { d_ramp = ramp; }
+ bool gate() const { return d_gate; }
+ void set_gate(bool gate) { d_gate = gate; }
+ bool unmuted() const { return (d_state == ST_UNMUTED || d_state == ST_ATTACK); }
+
+ virtual std::vector<float> squelch_range() const = 0;
+};
diff --git a/gnuradio-core/src/lib/general/gr_stream_to_streams.cc b/gnuradio-core/src/lib/general/gr_stream_to_streams.cc
new file mode 100644
index 0000000000..d4627964e6
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_stream_to_streams.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_stream_to_streams.h>
+#include <gr_io_signature.h>
+
+gr_stream_to_streams_sptr
+gr_make_stream_to_streams (size_t item_size, size_t nstreams)
+{
+ return gr_stream_to_streams_sptr (new gr_stream_to_streams (item_size, nstreams));
+}
+
+gr_stream_to_streams::gr_stream_to_streams (size_t item_size, size_t nstreams)
+ : gr_sync_decimator ("stream_to_streams",
+ gr_make_io_signature (1, 1, item_size),
+ gr_make_io_signature (nstreams,
+ nstreams, item_size),
+ nstreams)
+{
+}
+
+int
+gr_stream_to_streams::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ size_t item_size = output_signature()->sizeof_stream_item (0);
+
+ const char *in = (const char *) input_items[0];
+ char **outv = (char **) &output_items[0];
+ int nstreams = output_items.size();
+
+ for (int i = 0; i < noutput_items; i++){
+ for (int j = 0; j < nstreams; j++){
+ memcpy(outv[j], in, item_size);
+ outv[j] += item_size;
+ in += item_size;
+ }
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_stream_to_streams.h b/gnuradio-core/src/lib/general/gr_stream_to_streams.h
new file mode 100644
index 0000000000..3775e79b26
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_stream_to_streams.h
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_STREAM_TO_STREAMS_H
+#define INCLUDED_GR_STREAM_TO_STREAMS_H
+
+#include <gr_sync_decimator.h>
+
+class gr_stream_to_streams;
+typedef boost::shared_ptr<gr_stream_to_streams> gr_stream_to_streams_sptr;
+
+gr_stream_to_streams_sptr
+gr_make_stream_to_streams (size_t item_size, size_t nstreams);
+
+
+/*!
+ * \brief convert a stream of items into a N streams of items
+ * \ingroup block
+ *
+ * Converts a stream of N items into N streams of 1 item.
+ * Repeat ad infinitum.
+ */
+class gr_stream_to_streams : public gr_sync_decimator
+{
+ friend gr_stream_to_streams_sptr
+ gr_make_stream_to_streams (size_t item_size, size_t nstreams);
+
+ protected:
+ gr_stream_to_streams (size_t item_size, size_t nstreams);
+
+ public:
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_STREAM_TO_STREAMS_H */
diff --git a/gnuradio-core/src/lib/general/gr_stream_to_streams.i b/gnuradio-core/src/lib/general/gr_stream_to_streams.i
new file mode 100644
index 0000000000..59b93da048
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,stream_to_streams)
+
+gr_stream_to_streams_sptr
+gr_make_stream_to_streams (size_t itemsize, size_t nstreams);
+
+class gr_stream_to_streams : public gr_sync_decimator
+{
+ protected:
+ gr_stream_to_streams (size_t itemsize, size_t nstreams);
+
+ public:
+};
diff --git a/gnuradio-core/src/lib/general/gr_stream_to_vector.cc b/gnuradio-core/src/lib/general/gr_stream_to_vector.cc
new file mode 100644
index 0000000000..3d815cf59a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_stream_to_vector.cc
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_stream_to_vector.h>
+#include <gr_io_signature.h>
+
+gr_stream_to_vector_sptr
+gr_make_stream_to_vector (size_t item_size, size_t nitems_per_block)
+{
+ return gr_stream_to_vector_sptr (new gr_stream_to_vector (item_size, nitems_per_block));
+}
+
+gr_stream_to_vector::gr_stream_to_vector (size_t item_size, size_t nitems_per_block)
+ : gr_sync_decimator ("stream_to_vector",
+ gr_make_io_signature (1, 1, item_size),
+ gr_make_io_signature (1, 1, item_size * nitems_per_block),
+ nitems_per_block)
+{
+}
+
+int
+gr_stream_to_vector::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ size_t block_size = output_signature()->sizeof_stream_item (0);
+
+ const char *in = (const char *) input_items[0];
+ char *out = (char *) output_items[0];
+
+ memcpy (out, in, noutput_items * block_size);
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_stream_to_vector.h b/gnuradio-core/src/lib/general/gr_stream_to_vector.h
new file mode 100644
index 0000000000..a0a318b6ae
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_stream_to_vector.h
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_STREAM_TO_VECTOR_H
+#define INCLUDED_GR_STREAM_TO_VECTOR_H
+
+#include <gr_sync_decimator.h>
+
+class gr_stream_to_vector;
+typedef boost::shared_ptr<gr_stream_to_vector> gr_stream_to_vector_sptr;
+
+gr_stream_to_vector_sptr
+gr_make_stream_to_vector (size_t item_size, size_t nitems_per_block);
+
+
+/*!
+ * \brief convert a stream of items into a stream of blocks containing nitems_per_block
+ * \ingroup block
+ */
+class gr_stream_to_vector : public gr_sync_decimator
+{
+ friend gr_stream_to_vector_sptr
+ gr_make_stream_to_vector (size_t item_size, size_t nitems_per_block);
+
+ protected:
+ gr_stream_to_vector (size_t item_size, size_t nitems_per_block);
+
+ public:
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_STREAM_TO_VECTOR_H */
diff --git a/gnuradio-core/src/lib/general/gr_stream_to_vector.i b/gnuradio-core/src/lib/general/gr_stream_to_vector.i
new file mode 100644
index 0000000000..16550ac018
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,stream_to_vector)
+
+gr_stream_to_vector_sptr
+gr_make_stream_to_vector (size_t itemsize, size_t nitems_per_block);
+
+class gr_stream_to_vector : public gr_sync_decimator
+{
+ protected:
+ gr_stream_to_vector (size_t itemsize, size_t nitems_per_block);
+
+ public:
+};
diff --git a/gnuradio-core/src/lib/general/gr_streams_to_stream.cc b/gnuradio-core/src/lib/general/gr_streams_to_stream.cc
new file mode 100644
index 0000000000..9d05fbf762
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_streams_to_stream.cc
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_streams_to_stream.h>
+#include <gr_io_signature.h>
+
+gr_streams_to_stream_sptr
+gr_make_streams_to_stream (size_t item_size, size_t nstreams)
+{
+ return gr_streams_to_stream_sptr (new gr_streams_to_stream (item_size, nstreams));
+}
+
+gr_streams_to_stream::gr_streams_to_stream (size_t item_size, size_t nstreams)
+ : gr_sync_interpolator ("streams_to_stream",
+ gr_make_io_signature (nstreams, nstreams, item_size),
+ gr_make_io_signature (1, 1, item_size),
+ nstreams)
+{
+}
+
+int
+gr_streams_to_stream::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ size_t item_size = output_signature()->sizeof_stream_item (0);
+
+ const char **inv = (const char **) &input_items[0];
+ char *out = (char *) output_items[0];
+ int nstreams = input_items.size();
+
+ assert (noutput_items % nstreams == 0);
+ int ni = noutput_items / nstreams;
+
+ for (int i = 0; i < ni; i++){
+ for (int j = 0; j < nstreams; j++){
+ memcpy(out, inv[j], item_size);
+ out += item_size;
+ inv[j] += item_size;
+ }
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_streams_to_stream.h b/gnuradio-core/src/lib/general/gr_streams_to_stream.h
new file mode 100644
index 0000000000..86d390948e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_streams_to_stream.h
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_STREAMS_TO_STREAM_H
+#define INCLUDED_GR_STREAMS_TO_STREAM_H
+
+#include <gr_sync_interpolator.h>
+
+class gr_streams_to_stream;
+typedef boost::shared_ptr<gr_streams_to_stream> gr_streams_to_stream_sptr;
+
+gr_streams_to_stream_sptr
+gr_make_streams_to_stream (size_t item_size, size_t nstreams);
+
+
+/*!
+ * \brief Convert N streams of 1 item into a 1 stream of N items
+ * \ingroup block
+ *
+ * Convert N streams of 1 item into 1 stream of N items.
+ * Repeat ad infinitum.
+ */
+class gr_streams_to_stream : public gr_sync_interpolator
+{
+ friend gr_streams_to_stream_sptr
+ gr_make_streams_to_stream (size_t item_size, size_t nstreams);
+
+ protected:
+ gr_streams_to_stream (size_t item_size, size_t nstreams);
+
+ public:
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_STREAMS_TO_STREAM_H */
diff --git a/gnuradio-core/src/lib/general/gr_streams_to_stream.i b/gnuradio-core/src/lib/general/gr_streams_to_stream.i
new file mode 100644
index 0000000000..0f9e46fc5c
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,streams_to_stream)
+
+gr_streams_to_stream_sptr
+gr_make_streams_to_stream (size_t itemsize, size_t nstreams);
+
+class gr_streams_to_stream : public gr_sync_interpolator
+{
+ protected:
+ gr_streams_to_stream (size_t itemsize, size_t nstreams);
+
+ public:
+};
diff --git a/gnuradio-core/src/lib/general/gr_streams_to_vector.cc b/gnuradio-core/src/lib/general/gr_streams_to_vector.cc
new file mode 100644
index 0000000000..794254dd4c
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_streams_to_vector.cc
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_streams_to_vector.h>
+#include <gr_io_signature.h>
+
+gr_streams_to_vector_sptr
+gr_make_streams_to_vector (size_t item_size, size_t nstreams)
+{
+ return gr_streams_to_vector_sptr (new gr_streams_to_vector (item_size, nstreams));
+}
+
+gr_streams_to_vector::gr_streams_to_vector (size_t item_size, size_t nstreams)
+ : gr_sync_block ("streams_to_vector",
+ gr_make_io_signature (nstreams, nstreams, item_size),
+ gr_make_io_signature (1, 1, nstreams * item_size))
+{
+}
+
+int
+gr_streams_to_vector::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ size_t item_size = input_signature()->sizeof_stream_item(0);
+ int nstreams = input_items.size();
+
+ const char **inv = (const char **) &input_items[0];
+ char *out = (char *) output_items[0];
+
+ for (int i = 0; i < noutput_items; i++){
+ for (int j = 0; j < nstreams; j++){
+ memcpy(out, inv[j], item_size);
+ inv[j] += item_size;
+ out += item_size;
+ }
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_streams_to_vector.h b/gnuradio-core/src/lib/general/gr_streams_to_vector.h
new file mode 100644
index 0000000000..d3a8903587
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_streams_to_vector.h
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_STREAMS_TO_VECTOR_H
+#define INCLUDED_GR_STREAMS_TO_VECTOR_H
+
+#include <gr_sync_interpolator.h>
+
+class gr_streams_to_vector;
+typedef boost::shared_ptr<gr_streams_to_vector> gr_streams_to_vector_sptr;
+
+gr_streams_to_vector_sptr
+gr_make_streams_to_vector (size_t item_size, size_t nstreams);
+
+
+/*!
+ * \brief convert N streams of items to 1 stream of vector length N
+ * \ingroup block
+ */
+class gr_streams_to_vector : public gr_sync_block
+{
+ friend gr_streams_to_vector_sptr
+ gr_make_streams_to_vector (size_t item_size, size_t nstreams);
+
+ protected:
+ gr_streams_to_vector (size_t item_size, size_t nstreams);
+
+ public:
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_STREAMS_TO_VECTOR_H */
diff --git a/gnuradio-core/src/lib/general/gr_streams_to_vector.i b/gnuradio-core/src/lib/general/gr_streams_to_vector.i
new file mode 100644
index 0000000000..a69c2e5ada
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,streams_to_vector)
+
+gr_streams_to_vector_sptr
+gr_make_streams_to_vector (size_t itemsize, size_t nstreams);
+
+class gr_streams_to_vector : public gr_sync_block
+{
+ protected:
+ gr_streams_to_vector (size_t itemsize, size_t nstreams);
+
+ public:
+};
diff --git a/gnuradio-core/src/lib/general/gr_sub_XX.cc.t b/gnuradio-core/src/lib/general/gr_sub_XX.cc.t
new file mode 100644
index 0000000000..2cfdc6e946
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_sub_XX.cc.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ ()
+{
+ return @SPTR_NAME@ (new @NAME@ ());
+}
+
+@NAME@::@NAME@ ()
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (1, -1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@)))
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0];
+
+ int ninputs = input_items.size ();
+
+ if (ninputs == 1){ // negate
+ for (int i = 0; i < noutput_items; i++)
+ *optr++ = (@O_TYPE@) -((@I_TYPE@ *) input_items[0])[i];
+ }
+
+ else {
+ for (int i = 0; i < noutput_items; i++){
+ @I_TYPE@ acc = ((@I_TYPE@ *) input_items[0])[i];
+ for (int j = 1; j < ninputs; j++)
+ acc -= ((@I_TYPE@ *) input_items[j])[i];
+
+ *optr++ = (@O_TYPE@) acc;
+ }
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_sub_XX.h.t b/gnuradio-core/src/lib/general/gr_sub_XX.h.t
new file mode 100644
index 0000000000..025c077a07
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_sub_XX.h.t
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+/*!
+ * \brief output = input_0 - input_1 - ...)
+ * \ingroup block
+ *
+ * Subtract across all input streams.
+ */
+class @NAME@ : public gr_sync_block
+{
+ friend @SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+ @NAME@ ();
+
+ public:
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_sub_XX.i.t b/gnuradio-core/src/lib/general/gr_sub_XX.i.t
new file mode 100644
index 0000000000..8479aad683
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_sub_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+ @NAME@ ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_sync_block.cc b/gnuradio-core/src/lib/general/gr_sync_block.cc
new file mode 100644
index 0000000000..57b6c556b4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_sync_block.cc
@@ -0,0 +1,68 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_sync_block.h>
+
+gr_sync_block::gr_sync_block (const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature)
+ : gr_block(name, input_signature, output_signature)
+{
+ set_fixed_rate(true);
+}
+
+
+void
+gr_sync_block::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+ unsigned ninputs = ninput_items_required.size();
+ for (unsigned i = 0; i < ninputs; i++)
+ ninput_items_required[i] = fixed_rate_noutput_to_ninput (noutput_items);
+}
+
+int
+gr_sync_block::fixed_rate_noutput_to_ninput(int noutput_items)
+{
+ return noutput_items + history() - 1;
+}
+
+int
+gr_sync_block::fixed_rate_ninput_to_noutput(int ninput_items)
+{
+ return std::max(0, ninput_items - (int)history() + 1);
+}
+
+int
+gr_sync_block::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ int r = work (noutput_items, input_items, output_items);
+ if (r > 0)
+ consume_each (r);
+ return r;
+}
diff --git a/gnuradio-core/src/lib/general/gr_sync_block.h b/gnuradio-core/src/lib/general/gr_sync_block.h
new file mode 100644
index 0000000000..b4a2d008e5
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_sync_block.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_SYNC_BLOCK_H
+#define INCLUDED_GR_SYNC_BLOCK_H
+
+#include <gr_block.h>
+
+/*!
+ * \brief synchronous 1:1 input to output with history
+ * \ingroup block
+ *
+ * Override work to provide the signal processing implementation.
+ */
+class gr_sync_block : public gr_block
+{
+ protected:
+
+ gr_sync_block (const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature);
+
+ public:
+
+ /*!
+ * \brief just like gr_block::general_work, only this arranges to call consume_each for you
+ *
+ * The user must override work to define the signal processing code
+ */
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items) = 0;
+
+
+ // gr_sync_block overrides these to assist work
+ void forecast (int noutput_items, gr_vector_int &ninput_items_required);
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ int fixed_rate_ninput_to_noutput(int ninput);
+ int fixed_rate_noutput_to_ninput(int noutput);
+};
+
+#endif /* INCLUDED_GR_SYNC_BLOCK_H */
diff --git a/gnuradio-core/src/lib/general/gr_sync_block.i b/gnuradio-core/src/lib/general/gr_sync_block.i
new file mode 100644
index 0000000000..c078a8b898
--- /dev/null
+++ b/gnuradio-core/src/lib/general/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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+class gr_sync_block : public gr_block
+{
+ protected:
+
+ gr_sync_block (const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature);
+};
diff --git a/gnuradio-core/src/lib/general/gr_sync_decimator.cc b/gnuradio-core/src/lib/general/gr_sync_decimator.cc
new file mode 100644
index 0000000000..4b168a5da8
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_sync_decimator.cc
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_sync_decimator.h>
+
+gr_sync_decimator::gr_sync_decimator (const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature,
+ unsigned decimation)
+ : gr_sync_block (name, input_signature, output_signature)
+{
+ set_decimation (decimation);
+}
+
+void
+gr_sync_decimator::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+ unsigned ninputs = ninput_items_required.size ();
+ for (unsigned i = 0; i < ninputs; i++)
+ ninput_items_required[i] = fixed_rate_noutput_to_ninput(noutput_items);
+}
+
+int
+gr_sync_decimator::fixed_rate_noutput_to_ninput(int noutput_items)
+{
+ return noutput_items * decimation() + history() - 1;
+}
+
+int
+gr_sync_decimator::fixed_rate_ninput_to_noutput(int ninput_items)
+{
+ return std::max(0, ninput_items - (int)history() + 1) / decimation();
+}
+
+int
+gr_sync_decimator::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ int r = work (noutput_items, input_items, output_items);
+ if (r > 0)
+ consume_each (r * decimation ());
+ return r;
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_sync_decimator.h b/gnuradio-core/src/lib/general/gr_sync_decimator.h
new file mode 100644
index 0000000000..6cdd35a44b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_sync_decimator.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_SYNC_DECIMATOR_H
+#define INCLUDED_GR_SYNC_DECIMATOR_H
+
+#include <gr_sync_block.h>
+
+/*!
+ * \brief synchronous N:1 input to output with history
+ * \ingroup block
+ *
+ * Override work to provide the signal processing implementation.
+ */
+class gr_sync_decimator : public gr_sync_block
+{
+ private:
+ unsigned d_decimation;
+
+ protected:
+
+ gr_sync_decimator (const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature,
+ unsigned decimation);
+ public:
+
+ unsigned decimation () const { return d_decimation; }
+ void set_decimation (unsigned decimation)
+ {
+ d_decimation = decimation;
+ set_relative_rate (1.0 / decimation);
+ }
+
+ // gr_sync_decimator overrides these to assist work
+ void forecast (int noutput_items, gr_vector_int &ninput_items_required);
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ // derived classes should override work
+
+ int fixed_rate_ninput_to_noutput(int ninput);
+ int fixed_rate_noutput_to_ninput(int noutput);
+};
+
+
+#endif /* INCLUDED_GR_SYNC_DECIMATOR_H */
diff --git a/gnuradio-core/src/lib/general/gr_sync_decimator.i b/gnuradio-core/src/lib/general/gr_sync_decimator.i
new file mode 100644
index 0000000000..d9f6483af6
--- /dev/null
+++ b/gnuradio-core/src/lib/general/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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+class gr_sync_decimator : public gr_sync_block
+{
+ protected:
+
+ gr_sync_decimator (const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature,
+ unsigned decimation);
+};
diff --git a/gnuradio-core/src/lib/general/gr_sync_interpolator.cc b/gnuradio-core/src/lib/general/gr_sync_interpolator.cc
new file mode 100644
index 0000000000..024d7e7802
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_sync_interpolator.cc
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_sync_interpolator.h>
+
+gr_sync_interpolator::gr_sync_interpolator (const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature,
+ unsigned interpolation)
+ : gr_sync_block (name, input_signature, output_signature)
+{
+ set_interpolation (interpolation);
+}
+
+void
+gr_sync_interpolator::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+ unsigned ninputs = ninput_items_required.size ();
+ for (unsigned i = 0; i < ninputs; i++)
+ ninput_items_required[i] = fixed_rate_noutput_to_ninput(noutput_items);
+}
+
+int
+gr_sync_interpolator::fixed_rate_noutput_to_ninput(int noutput_items)
+{
+ return noutput_items / interpolation() + history() - 1;
+}
+
+int
+gr_sync_interpolator::fixed_rate_ninput_to_noutout(int ninput_items)
+{
+ return std::max(0, ninput_items - (int)history() + 1) * interpolation();
+}
+
+int
+gr_sync_interpolator::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ int r = work (noutput_items, input_items, output_items);
+ if (r > 0)
+ consume_each (r / interpolation ());
+ return r;
+}
+
+
diff --git a/gnuradio-core/src/lib/general/gr_sync_interpolator.h b/gnuradio-core/src/lib/general/gr_sync_interpolator.h
new file mode 100644
index 0000000000..914ea8e5a9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_sync_interpolator.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_SYNC_INTERPOLATOR_H
+#define INCLUDED_GR_SYNC_INTERPOLATOR_H
+
+#include <gr_sync_block.h>
+
+/*!
+ * \brief synchronous 1:N input to output with history
+ * \ingroup block
+ *
+ * Override work to provide the signal processing implementation.
+ */
+class gr_sync_interpolator : public gr_sync_block
+{
+ private:
+ unsigned d_interpolation;
+
+ protected:
+ gr_sync_interpolator (const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature,
+ unsigned interpolation);
+ public:
+
+ unsigned interpolation () const { return d_interpolation; }
+ void set_interpolation (unsigned interpolation)
+ {
+ d_interpolation = interpolation;
+ set_relative_rate (1.0 * interpolation);
+ set_output_multiple (interpolation);
+ }
+
+ // gr_sync_interpolator overrides these to assist work
+ void forecast (int noutput_items, gr_vector_int &ninput_items_required);
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ // derived classes should override work
+
+ int fixed_rate_ninput_to_noutout(int ninput);
+ int fixed_rate_noutput_to_ninput(int noutput);
+};
+
+
+#endif /* INCLUDED_GR_SYNC_INTERPOLATOR_H */
diff --git a/gnuradio-core/src/lib/general/gr_sync_interpolator.i b/gnuradio-core/src/lib/general/gr_sync_interpolator.i
new file mode 100644
index 0000000000..9b69d334c4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+class gr_sync_interpolator : public gr_sync_block
+{
+ protected:
+
+ gr_sync_interpolator (const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature,
+ unsigned interpolation);
+};
diff --git a/gnuradio-core/src/lib/general/gr_test.cc b/gnuradio-core/src/lib/general/gr_test.cc
new file mode 100644
index 0000000000..17263f490e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_test.cc
@@ -0,0 +1,176 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_test.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <iostream>
+
+gr_test_sptr gr_make_test (const std::string &name,
+ int min_inputs, int max_inputs, unsigned int sizeof_input_item,
+ int min_outputs, int max_outputs, unsigned int sizeof_output_item,
+ unsigned int history,unsigned int output_multiple,double relative_rate,
+ bool fixed_rate,gr_consume_type_t cons_type, gr_produce_type_t prod_type)
+{
+ return gr_test_sptr (new gr_test (name, min_inputs,max_inputs,sizeof_input_item,
+ min_outputs,max_outputs,sizeof_output_item,
+ history,output_multiple,relative_rate,fixed_rate,cons_type, prod_type));
+}
+
+ gr_test::gr_test (const std::string &name,int min_inputs, int max_inputs, unsigned int sizeof_input_item,
+ int min_outputs, int max_outputs, unsigned int sizeof_output_item,
+ unsigned int history,unsigned int output_multiple,double relative_rate,
+ bool fixed_rate,gr_consume_type_t cons_type, gr_produce_type_t prod_type): gr_block (name,
+ gr_make_io_signature (min_inputs, max_inputs, sizeof_input_item),
+ gr_make_io_signature (min_outputs, max_outputs, sizeof_output_item)),
+ d_sizeof_input_item(sizeof_input_item),
+ d_sizeof_output_item(sizeof_output_item),
+ d_check_topology(true),
+ d_consume_type(cons_type),
+ d_min_consume(0),
+ d_max_consume(0),
+ d_produce_type(prod_type),
+ d_min_produce(0),
+ d_max_produce(0)
+ {
+ set_history(history);
+ set_output_multiple(output_multiple);
+ set_relative_rate(relative_rate);
+ set_fixed_rate(fixed_rate);
+ }
+
+int
+gr_test::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ //touch all inputs and outputs to detect segfaults
+ unsigned ninputs = input_items.size ();
+ unsigned noutputs= output_items.size();
+ for (unsigned i = 0; i < ninputs; i++)
+ {
+ char * in=(char *)input_items[i];
+ if (ninput_items[i]< (int)(noutput_items+history()))
+ {
+ std::cerr << "ERROR: ninput_items[" << i << "] < noutput_items+history()" << std::endl;
+ std::cerr << "ninput_items[" << i << "] = " << ninput_items[i] << std::endl;
+ std::cerr << "noutput_items+history() = " << noutput_items+history() << std::endl;
+ std::cerr << "noutput_items = " << noutput_items << std::endl;
+ std::cerr << "history() = " << history() << std::endl;
+ throw std::runtime_error ("gr_test");
+ } else
+ {
+ for (int j=0;j<ninput_items[i];j++)
+ {
+ //Touch every available input_item
+ //We use a class variable to avoid the compiler to optimize this away
+ for(unsigned int k=0;k<d_sizeof_input_item;k++)
+ d_temp= in[j*d_sizeof_input_item+k];
+ }
+ switch (d_consume_type)
+ {
+ case CONSUME_NOUTPUT_ITEMS:
+ consume(i,noutput_items);
+ break;
+ case CONSUME_NOUTPUT_ITEMS_LIMIT_MAX:
+ consume(i,std::min(noutput_items,d_max_consume));
+ break;
+ case CONSUME_NOUTPUT_ITEMS_LIMIT_MIN:
+ consume(i,std::min(std::max(noutput_items,d_min_consume),ninput_items[i]));
+ break;
+ case CONSUME_ALL_AVAILABLE:
+ consume(i,ninput_items[i]);
+ break;
+ case CONSUME_ALL_AVAILABLE_LIMIT_MAX:
+ consume(i,std::min(ninput_items[i],d_max_consume));
+ break;
+/* //This could result in segfault, uncomment if you want to test this
+ case CONSUME_ALL_AVAILABLE_LIMIT_MIN:
+ consume(i,std::max(ninput_items[i],d_max_consume));
+ break;*/
+ case CONSUME_ZERO:
+ consume(i,0);
+ break;
+ case CONSUME_ONE:
+ consume(i,1);
+ break;
+ case CONSUME_MINUS_ONE:
+ consume(i,-1);
+ break;
+ default:
+ consume(i,noutput_items);
+ }
+ }
+ }
+ for (unsigned i = 0; i < noutputs; i++)
+ {
+ char * out=(char *)output_items[i];
+ {
+ for (int j=0;j<noutput_items;j++)
+ {
+ //Touch every available output_item
+ for(unsigned int k=0;k<d_sizeof_output_item;k++)
+ out[j*d_sizeof_input_item+k]=0;
+ }
+ }
+ }
+ //Now copy input to output untill max ninputs or max noutputs is reached
+ int common_nports=std::min(ninputs,noutputs);
+ if(d_sizeof_output_item==d_sizeof_input_item);
+ for (int i = 0; i < common_nports; i++)
+ {
+ memcpy(output_items[i],input_items[i],noutput_items*d_sizeof_input_item);
+ }
+ int noutput_items_produced=0;
+ switch (d_produce_type){
+ case PRODUCE_NOUTPUT_ITEMS:
+ noutput_items_produced=noutput_items;
+ break;
+ case PRODUCE_NOUTPUT_ITEMS_LIMIT_MAX:
+ noutput_items_produced=std::min(noutput_items,d_max_produce);
+ break;
+/* //This could result in segfault, uncomment if you want to test this
+ case PRODUCE_NOUTPUT_ITEMS_LIMIT_MIN:
+ noutput_items_produced=std::max(noutput_items,d_min_produce);
+ break;*/
+ case PRODUCE_ZERO:
+ noutput_items_produced=0;
+ break;
+ case PRODUCE_ONE:
+ noutput_items_produced=1;
+ break;
+ case PRODUCE_MINUS_ONE:
+ noutput_items_produced=-1;
+ break;
+ default:
+ noutput_items_produced=noutput_items;
+ }
+ return noutput_items_produced;
+ }
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_test.h b/gnuradio-core/src/lib/general/gr_test.h
new file mode 100644
index 0000000000..7bda9ae0ad
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_test.h
@@ -0,0 +1,199 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_TEST_H
+#define INCLUDED_GR_TEST_H
+
+#include <gr_block.h>
+#include <string>
+#include "gr_test_types.h"
+
+class gr_test;
+typedef boost::shared_ptr<gr_test> gr_test_sptr;
+
+// public constructor
+gr_test_sptr gr_make_test (const std::string &name=std::string("gr_test"),
+ int min_inputs=1, int max_inputs=1, unsigned int sizeof_input_item=1,
+ int min_outputs=1, int max_outputs=1, unsigned int sizeof_output_item=1,
+ unsigned int history=1,unsigned int output_multiple=1,double relative_rate=1.0,
+ bool fixed_rate=true,gr_consume_type_t cons_type=CONSUME_NOUTPUT_ITEMS, gr_produce_type_t prod_type=PRODUCE_NOUTPUT_ITEMS);
+
+/*!
+ * \brief Test class for testing runtime system (setting up buffers and such.)
+ * \ingroup block
+ *
+ * This block does not do any usefull actual data processing.
+ * It just exposes setting all standard block parameters using the contructor or public methods.
+ *
+ * This block can be usefull when testing the runtime system.
+ * You can force this block to have a large history, decimation
+ * factor and/or large output_multiple.
+ * The runtime system should detect this and create large enough buffers
+ * all through the signal chain.
+ *
+ */
+
+
+
+
+class gr_test : public gr_block {
+
+ public:
+
+ ~gr_test (){}
+
+int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ // ----------------------------------------------------------------
+ // override these to define your behavior
+ // ----------------------------------------------------------------
+
+ /*!
+ * \brief Estimate input requirements given output request
+ *
+ * \param noutput_items number of output items to produce
+ * \param ninput_items_required number of input items required on each input stream
+ *
+ * Given a request to product \p noutput_items, estimate the number of
+ * data items required on each input stream. The estimate doesn't have
+ * to be exact, but should be close.
+ */
+ void forecast (int noutput_items,
+ gr_vector_int &ninput_items_required)
+ {
+ unsigned ninputs = ninput_items_required.size ();
+ for (unsigned i = 0; i < ninputs; i++)
+ ninput_items_required[i] = (int)((double)noutput_items / relative_rate()) + (int)history();
+ }
+
+
+ /*!
+ * \brief Force check topology to return true or false.
+ *
+ * \param check_topology value to return when check_topology is called (true or false)
+ * default check_topology returns true
+ *
+ */
+ void set_check_topology (bool check_topology){ d_check_topology=check_topology;}
+
+ /*!
+ * \brief Confirm that ninputs and noutputs is an acceptable combination.
+ *
+ * \param ninputs number of input streams connected
+ * \param noutputs number of output streams connected
+ *
+ * \returns true if this is a valid configuration for this block.
+ *
+ * This function is called by the runtime system whenever the
+ * topology changes. Most classes do not need to override this.
+ * This check is in addition to the constraints specified by the input
+ * and output gr_io_signatures.
+ */
+ bool check_topology (int ninputs, int noutputs) { return d_check_topology;}
+
+ // ----------------------------------------------------------------
+ /*
+ * The following two methods provide special case info to the
+ * scheduler in the event that a block has a fixed input to output
+ * ratio. gr_sync_block, gr_sync_decimator and gr_sync_interpolator
+ * override these. If you're fixed rate, subclass one of those.
+ */
+ /*!
+ * \brief Given ninput samples, return number of output samples that will be produced.
+ * N.B. this is only defined if fixed_rate returns true.
+ * Generally speaking, you don't need to override this.
+ */
+ int fixed_rate_ninput_to_noutput(int ninput) { return (int)((double)ninput/relative_rate()); }
+
+ /*!
+ * \brief Given noutput samples, return number of input samples required to produce noutput.
+ * N.B. this is only defined if fixed_rate returns true.
+ */
+ int fixed_rate_noutput_to_ninput(int noutput) { return (int)((double)noutput*relative_rate()); }
+
+ /*!
+ * \brief Set if fixed rate should return true.
+ * N.B. This is normally a private method but we make it available here as public.
+ */
+ void set_fixed_rate_public(bool fixed_rate){ set_fixed_rate(fixed_rate);}
+
+ /*!
+ * \brief Set the consume pattern.
+ *
+ * \param cons_type which consume pattern to use
+ */
+ void set_consume_type (gr_consume_type_t cons_type) { d_consume_type=cons_type;}
+
+ /*!
+ * \brief Set the consume limit.
+ *
+ * \param limit min or maximum items to consume (depending on consume_type)
+ */
+ void set_consume_limit (unsigned int limit) { d_min_consume=limit; d_max_consume=limit;}
+
+ /*!
+ * \brief Set the produce pattern.
+ *
+ * \param prod_type which produce pattern to use
+ */
+ void set_produce_type (gr_produce_type_t prod_type) { d_produce_type=prod_type;}
+
+ /*!
+ * \brief Set the produce limit.
+ *
+ * \param limit min or maximum items to produce (depending on produce_type)
+ */
+ void set_produce_limit (unsigned int limit) { d_min_produce=limit; d_max_produce=limit;}
+
+ // ----------------------------------------------------------------------------
+
+
+
+ protected:
+ unsigned int d_sizeof_input_item;
+ unsigned int d_sizeof_output_item;
+ bool d_check_topology;
+ char d_temp;
+ gr_consume_type_t d_consume_type;
+ int d_min_consume;
+ int d_max_consume;
+ gr_produce_type_t d_produce_type;
+ int d_min_produce;
+ int d_max_produce;
+ gr_test (const std::string &name,int min_inputs, int max_inputs, unsigned int sizeof_input_item,
+ int min_outputs, int max_outputs, unsigned int sizeof_output_item,
+ unsigned int history,unsigned int output_multiple,double relative_rate,
+ bool fixed_rate,gr_consume_type_t cons_type, gr_produce_type_t prod_type);
+
+
+
+ friend gr_test_sptr gr_make_test (const std::string &name,int min_inputs, int max_inputs, unsigned int sizeof_input_item,
+ int min_outputs, int max_outputs, unsigned int sizeof_output_item,
+ unsigned int history,unsigned int output_multiple,double relative_rate,
+ bool fixed_rate,gr_consume_type_t cons_type, gr_produce_type_t prod_type);
+};
+
+
+
+#endif /* INCLUDED_GR_TEST_H */
diff --git a/gnuradio-core/src/lib/general/gr_test.i b/gnuradio-core/src/lib/general/gr_test.i
new file mode 100644
index 0000000000..e6f922c074
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,test);
+
+
+class gr_test;
+typedef boost::shared_ptr<gr_test> gr_test_sptr;
+
+
+// public constructor
+gr_test_sptr gr_make_test (const std::string &name=std::string("gr_test"),
+ int min_inputs=1, int max_inputs=1, unsigned int sizeof_input_item=1,
+ int min_outputs=1, int max_outputs=1, unsigned int sizeof_output_item=1,
+ unsigned int history=1,unsigned int output_multiple=1,double relative_rate=1.0,
+ bool fixed_rate=true,gr_consume_type_t cons_type=CONSUME_NOUTPUT_ITEMS, gr_produce_type_t prod_type=PRODUCE_NOUTPUT_ITEMS);
+
+
+class gr_test : public gr_block {
+
+ public:
+
+ ~gr_test ();
+ void forecast (int noutput_items,
+ gr_vector_int &ninput_items_required);
+ void set_check_topology (bool check_topology);
+ bool check_topology (int ninputs, int noutputs);
+ int fixed_rate_ninput_to_noutput(int ninput);
+ int fixed_rate_noutput_to_ninput(int noutput);
+ void set_fixed_rate_public(bool fixed_rate);
+ void set_consume_type (gr_consume_type_t cons_type);
+ void set_consume_limit (unsigned int limit);
+ void set_produce_type (gr_produce_type_t prod_type);
+ void set_produce_limit (unsigned int limit);
+
+ protected:
+ gr_test (const std::string &name,int min_inputs, int max_inputs, unsigned int sizeof_input_item,
+ int min_outputs, int max_outputs, unsigned int sizeof_output_item,
+ unsigned int history,unsigned int output_multiple,double relative_rate,
+ bool fixed_rate,gr_consume_type_t cons_type, gr_produce_type_t prod_type);
+
+};
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_test_types.h b/gnuradio-core/src/lib/general/gr_test_types.h
new file mode 100644
index 0000000000..92fe3f742d
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_TEST_TYPES_H
+#define INCLUDED_GR_TEST_TYPES_H
+
+typedef enum {
+ CONSUME_NOUTPUT_ITEMS=0,
+ CONSUME_NOUTPUT_ITEMS_LIMIT_MAX=1,
+ CONSUME_NOUTPUT_ITEMS_LIMIT_MIN=2,
+ CONSUME_ALL_AVAILABLE=3,
+ CONSUME_ALL_AVAILABLE_LIMIT_MAX=4,
+ /*CONSUME_ALL_AVAILABLE_LIMIT_MIN=5,*/
+ CONSUME_ZERO=6,
+ CONSUME_ONE=7,
+ CONSUME_MINUS_ONE=8
+ } gr_consume_type_t;
+
+typedef enum {
+ PRODUCE_NOUTPUT_ITEMS=0,
+ PRODUCE_NOUTPUT_ITEMS_LIMIT_MAX=1,
+ /*PRODUCE_NOUTPUT_ITEMS_LIMIT_MIN=2,*/
+ PRODUCE_ZERO=6,
+ PRODUCE_ONE=7,
+ PRODUCE_MINUS_ONE=8
+ } gr_produce_type_t;
+
+#endif /* INCLUDED_GR_TEST_TYPES_H */
diff --git a/gnuradio-core/src/lib/general/gr_threshold_ff.cc b/gnuradio-core/src/lib/general/gr_threshold_ff.cc
new file mode 100644
index 0000000000..4041f46731
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_threshold_ff.cc
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// WARNING: this file is machine generated. Edits will be over written
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_threshold_ff.h>
+#include <gr_io_signature.h>
+
+gr_threshold_ff_sptr
+gr_make_threshold_ff (float lo, float hi, float initial_state)
+{
+ return gr_threshold_ff_sptr (new gr_threshold_ff (lo, hi, initial_state));
+}
+
+gr_threshold_ff::gr_threshold_ff (float lo, float hi, float initial_state)
+ : gr_sync_block ("threshold_ff",
+ gr_make_io_signature (1, 1, sizeof (float)),
+ gr_make_io_signature (1, 1, sizeof (float))),
+ d_lo (lo), d_hi (hi), d_last_state (initial_state)
+{
+}
+
+int
+gr_threshold_ff::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+ float *out = (float *) output_items[0];
+
+
+ for(int i=0; i<noutput_items; i++) {
+ if (in[i] > d_hi) {
+ out[i] = 1.0;
+ d_last_state = 1.0;
+ } else if (in[i] < d_lo) {
+ out[i] = 0.0;
+ d_last_state = 0.0;
+ } else
+ out[i] = d_last_state;
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_threshold_ff.h b/gnuradio-core/src/lib/general/gr_threshold_ff.h
new file mode 100644
index 0000000000..30ca67f5c6
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_threshold_ff.h
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_THRESHOLD_FF_H
+#define INCLUDED_GR_THRESHOLD_FF_H
+
+#include <gr_sync_block.h>
+
+class gr_threshold_ff;
+typedef boost::shared_ptr<gr_threshold_ff> gr_threshold_ff_sptr;
+
+gr_threshold_ff_sptr gr_make_threshold_ff (float lo, float hi, float initial_state=0);
+
+/*!
+ * \brief
+ * \ingroup block
+ */
+class gr_threshold_ff : public gr_sync_block
+{
+ friend gr_threshold_ff_sptr gr_make_threshold_ff (float lo, float hi, float initial_state);
+
+ float d_lo,d_hi; // the constant
+ float d_last_state;
+ gr_threshold_ff (float lo, float hi, float initial_state);
+
+ public:
+ float lo () const { return d_lo; }
+ void set_lo (float lo) { d_lo = lo; }
+ float hi () const { return d_hi; }
+ void set_hi (float hi) { d_hi = hi; }
+ float last_state () const { return d_last_state; }
+ void set_last_state (float last_state) { d_last_state = last_state; }
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_threshold_ff.i b/gnuradio-core/src/lib/general/gr_threshold_ff.i
new file mode 100644
index 0000000000..2fcf1deab2
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,threshold_ff);
+
+gr_threshold_ff_sptr gr_make_threshold_ff (float lo, float hi, float initial_state=0);
+
+class gr_threshold_ff : public gr_sync_block
+{
+ private:
+ gr_threshold_ff (float lo, float hi, float initial_state);
+
+ public:
+ float lo () const { return d_lo; }
+ void set_lo (float lo) { d_lo = lo; }
+ float hi () const { return d_hi; }
+ void set_hi (float hi) { d_hi = hi; }
+ float last_state () const { return d_last_state; }
+ void set_last_state (float last_state) { d_last_state = last_state; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_throttle.cc b/gnuradio-core/src/lib/general/gr_throttle.cc
new file mode 100644
index 0000000000..9fbf23eddd
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_throttle.cc
@@ -0,0 +1,109 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_throttle.h>
+#include <gr_io_signature.h>
+#include <errno.h>
+#include <stdio.h>
+#include <math.h>
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+
+#ifdef HAVE_NANOSLEEP
+void
+gr_nanosleep(struct timespec *ts)
+{
+ struct timespec *req = ts;
+ struct timespec rem;
+ int r = nanosleep(req, &rem);
+ while (r < 0 && errno == EINTR){
+ req = &rem;
+ r = nanosleep(req, &rem);
+ }
+ if (r < 0)
+ perror ("gr_nanosleep");
+}
+#endif
+
+gr_throttle_sptr
+gr_make_throttle(size_t itemsize, double samples_per_sec)
+{
+ return gr_throttle_sptr(new gr_throttle(itemsize, samples_per_sec));
+}
+
+gr_throttle::gr_throttle(size_t itemsize, double samples_per_sec)
+ : gr_sync_block("throttle",
+ gr_make_io_signature(1, 1, itemsize),
+ gr_make_io_signature(1, 1, itemsize)),
+ d_itemsize(itemsize), d_samples_per_sec(samples_per_sec),
+ d_total_samples(0)
+{
+#ifdef HAVE_GETTIMEOFDAY
+ gettimeofday(&d_start, 0);
+#endif
+}
+
+gr_throttle::~gr_throttle()
+{
+}
+
+int
+gr_throttle::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const char *in = (const char *) input_items[0];
+ char *out = (char *) output_items[0];
+
+#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_NANOSLEEP)
+ //
+ // If our average sample rate exceeds our target sample rate,
+ // delay long enough to reduce to our target rate.
+ //
+ struct timeval now;
+ gettimeofday(&now, 0);
+ long t_usec = now.tv_usec - d_start.tv_usec;
+ long t_sec = now.tv_sec - d_start.tv_sec;
+ double t = (double)t_sec + (double)t_usec * 1e-6;
+ if (t < 1e-6) // avoid unlikely divide by zero
+ t = 1e-6;
+
+ double actual_samples_per_sec = d_total_samples / t;
+ if (actual_samples_per_sec > d_samples_per_sec){ // need to delay
+ double delay = d_total_samples / d_samples_per_sec - t;
+ struct timespec ts;
+ ts.tv_sec = (time_t)floor(delay);
+ ts.tv_nsec = (long)((delay - floor(delay)) * 1e9);
+ gr_nanosleep(&ts);
+ }
+#endif
+
+ memcpy(out, in, noutput_items * d_itemsize);
+ d_total_samples += noutput_items;
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_throttle.h b/gnuradio-core/src/lib/general/gr_throttle.h
new file mode 100644
index 0000000000..c926a405fe
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_throttle.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_THROTTLE_H
+#define INCLUDED_GR_THROTTLE_H
+
+#include <gr_sync_block.h>
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+class gr_throttle;
+typedef boost::shared_ptr<gr_throttle> gr_throttle_sptr;
+
+
+gr_throttle_sptr gr_make_throttle(size_t itemsize, double samples_per_sec);
+
+/*!
+ * \brief throttle flow of samples such that the average rate does not exceed samples_per_sec.
+ * \ingroup block
+ *
+ * input: one stream of itemsize; output: one stream of itemsize
+ */
+class gr_throttle : public gr_sync_block
+{
+ friend gr_throttle_sptr gr_make_throttle(size_t itemsize, double samples_per_sec);
+ size_t d_itemsize;
+ double d_samples_per_sec;
+ double d_total_samples;
+#ifdef HAVE_SYS_TIME_H
+ struct timeval d_start;
+#endif
+
+ gr_throttle(size_t itemsize, double samples_per_sec);
+
+public:
+ ~gr_throttle();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_THROTTLE_H */
diff --git a/gnuradio-core/src/lib/general/gr_throttle.i b/gnuradio-core/src/lib/general/gr_throttle.i
new file mode 100644
index 0000000000..eb237b352a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_throttle.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,throttle);
+
+gr_throttle_sptr gr_make_throttle (size_t itemsize, double samples_per_sec);
+
+class gr_throttle : public gr_sync_block
+{
+ gr_throttle (size_t itemsize, double samples_per_sec);
+};
diff --git a/gnuradio-core/src/lib/general/gr_uchar_to_float.cc b/gnuradio-core/src/lib/general/gr_uchar_to_float.cc
new file mode 100644
index 0000000000..e162d777fa
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_uchar_to_float.cc
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_uchar_to_float.h>
+#include <gr_io_signature.h>
+#include <gri_uchar_to_float.h>
+
+gr_uchar_to_float_sptr
+gr_make_uchar_to_float ()
+{
+ return gr_uchar_to_float_sptr (new gr_uchar_to_float ());
+}
+
+gr_uchar_to_float::gr_uchar_to_float ()
+ : gr_sync_block ("gr_uchar_to_float",
+ gr_make_io_signature (1, 1, sizeof (unsigned char)),
+ gr_make_io_signature (1, 1, sizeof (float)))
+{
+}
+
+int
+gr_uchar_to_float::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ float *out = (float *) output_items[0];
+
+ gri_uchar_to_float (in, out, noutput_items);
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_uchar_to_float.h b/gnuradio-core/src/lib/general/gr_uchar_to_float.h
new file mode 100644
index 0000000000..7de5572694
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_uchar_to_float.h
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_UCHAR_TO_FLOAT_H
+#define INCLUDED_GR_UCHAR_TO_FLOAT_H
+
+#include <gr_sync_block.h>
+
+class gr_uchar_to_float;
+typedef boost::shared_ptr<gr_uchar_to_float> gr_uchar_to_float_sptr;
+
+gr_uchar_to_float_sptr
+gr_make_uchar_to_float ();
+
+/*!
+ * \brief Convert stream of unsigned chars to a stream of float
+ * \ingroup converter
+ */
+
+class gr_uchar_to_float : public gr_sync_block
+{
+ friend gr_uchar_to_float_sptr gr_make_uchar_to_float ();
+ gr_uchar_to_float ();
+
+ public:
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_UCHAR_TO_FLOAT_H */
diff --git a/gnuradio-core/src/lib/general/gr_uchar_to_float.i b/gnuradio-core/src/lib/general/gr_uchar_to_float.i
new file mode 100644
index 0000000000..4b7e8bce6d
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,uchar_to_float)
+
+gr_uchar_to_float_sptr gr_make_uchar_to_float ();
+
+class gr_uchar_to_float : public gr_sync_block
+{
+ gr_uchar_to_float ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.cc b/gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.cc
new file mode 100644
index 0000000000..399bc11122
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.cc
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_unpack_k_bits_bb.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <iostream>
+
+gr_unpack_k_bits_bb_sptr gr_make_unpack_k_bits_bb (unsigned k)
+{
+ return gr_unpack_k_bits_bb_sptr (new gr_unpack_k_bits_bb (k));
+}
+
+
+gr_unpack_k_bits_bb::gr_unpack_k_bits_bb (unsigned k)
+ : gr_sync_interpolator ("unpack_k_bits_bb",
+ gr_make_io_signature (1, 1, sizeof (unsigned char)),
+ gr_make_io_signature (1, 1, sizeof (unsigned char)),
+ k),
+ d_k (k)
+{
+ if (d_k == 0)
+ throw std::out_of_range ("interpolation must be > 0");
+}
+
+gr_unpack_k_bits_bb::~gr_unpack_k_bits_bb ()
+{
+}
+
+int
+gr_unpack_k_bits_bb::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+
+ int n = 0;
+ for (unsigned int i = 0; i < noutput_items/d_k; i++){
+ unsigned int t = in[i];
+ for (int j = d_k - 1; j >= 0; j--)
+ out[n++] = (t >> j) & 0x01;
+ }
+
+ assert(n == noutput_items);
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.h b/gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.h
new file mode 100644
index 0000000000..38a8bc1a90
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_unpack_k_bits_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_UNPACK_K_BITS_BB_H
+#define INCLUDED_GR_UNPACK_K_BITS_BB_H
+
+#include <gr_sync_interpolator.h>
+
+class gr_unpack_k_bits_bb;
+typedef boost::shared_ptr<gr_unpack_k_bits_bb> gr_unpack_k_bits_bb_sptr;
+gr_unpack_k_bits_bb_sptr gr_make_unpack_k_bits_bb (unsigned k);
+
+class gr_unpack_k_bits_bb;
+
+/*!
+ * \brief Converts a byte with k relevent bits to k output bytes with 1 bit in the LSB
+ */
+class gr_unpack_k_bits_bb : public gr_sync_interpolator
+{
+ private:
+ friend gr_unpack_k_bits_bb_sptr gr_make_unpack_k_bits_bb (unsigned k);
+
+ gr_unpack_k_bits_bb (unsigned k);
+
+ unsigned d_k; // number of relevent bits to unpack into k output bytes
+
+ public:
+ ~gr_unpack_k_bits_bb ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.i b/gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.i
new file mode 100644
index 0000000000..eb6bda9d8f
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,unpack_k_bits_bb)
+
+gr_unpack_k_bits_bb_sptr gr_make_unpack_k_bits_bb (int k);
+
+class gr_unpack_k_bits_bb : public gr_sync_interpolator
+{
+ private:
+ gr_unpack_k_bits_bb (int k);
+
+ public:
+ ~gr_unpack_k_bits_bb ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_unpacked_to_packed_XX.cc.t b/gnuradio-core/src/lib/general/gr_unpacked_to_packed_XX.cc.t
new file mode 100644
index 0000000000..7d5d72e651
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_unpacked_to_packed_XX.cc.t
@@ -0,0 +1,125 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+
+static const unsigned int BITS_PER_TYPE = sizeof(@O_TYPE@) * 8;
+
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness)
+{
+ return @SPTR_NAME@
+ (new @NAME@ (bits_per_chunk,endianness));
+}
+
+@NAME@::@NAME@ (unsigned int bits_per_chunk,
+ gr_endianness_t endianness)
+ : gr_block ("@BASE_NAME@",
+ gr_make_io_signature (1, -1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, -1, sizeof (@O_TYPE@))),
+ d_bits_per_chunk(bits_per_chunk),d_endianness(endianness),d_index(0)
+{
+ assert (bits_per_chunk <= BITS_PER_TYPE);
+ assert (bits_per_chunk > 0);
+
+ set_relative_rate (bits_per_chunk/(1.0 * BITS_PER_TYPE));
+}
+
+void
+@NAME@::forecast(int noutput_items, gr_vector_int &ninput_items_required)
+{
+ int input_required = (int) ceil( (d_index+noutput_items * 1.0 * BITS_PER_TYPE)/d_bits_per_chunk);
+ unsigned ninputs = ninput_items_required.size();
+ for (unsigned int i = 0; i < ninputs; i++) {
+ ninput_items_required[i] = input_required;
+ }
+}
+
+unsigned int
+get_bit_be1 (const @I_TYPE@ *in_vector,unsigned int bit_addr, unsigned int bits_per_chunk) {
+ unsigned int byte_addr = (int)bit_addr/bits_per_chunk;
+ @I_TYPE@ x = in_vector[byte_addr];
+ unsigned int residue = bit_addr - byte_addr * bits_per_chunk;
+ //printf("Bit addr %d byte addr %d residue %d val %d\n",bit_addr,byte_addr,residue,(x>>(bits_per_chunk-1-residue))&1);
+ return (x >> (bits_per_chunk-1-residue))&1;
+}
+
+int
+@NAME@::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ assert (input_items.size() == output_items.size());
+ int nstreams = input_items.size();
+
+ for (int m=0; m< nstreams; m++) {
+ const @I_TYPE@ *in = (@I_TYPE@ *) input_items[m];
+ @O_TYPE@ *out = (@O_TYPE@ *) output_items[m];
+
+ // per stream processing
+
+ //assert((ninput_items[m]-d_index)*d_bits_per_chunk >= noutput_items*BITS_PER_TYPE);
+
+ switch(d_endianness){
+
+ case GR_MSB_FIRST:
+ for(int i=0;i<noutput_items;i++) {
+ @O_TYPE@ tmp=0;
+ for(unsigned int j=0; j<BITS_PER_TYPE; j++) {
+ tmp = (tmp<<1) | get_bit_be1(in,d_index,d_bits_per_chunk);
+ d_index++;
+ }
+ out[i] = tmp;
+ }
+ break;
+
+ case GR_LSB_FIRST:
+ for(int i=0;i<noutput_items;i++) {
+ unsigned long tmp=0;
+ for(unsigned int j=0; j<BITS_PER_TYPE; j++) {
+ tmp = (tmp>>1)| (get_bit_be1(in,d_index,d_bits_per_chunk)<<(BITS_PER_TYPE-1));
+ d_index++;
+ }
+ out[i] = tmp;
+ }
+ break;
+
+ default:
+ assert(0);
+ }
+ }
+
+ consume_each ((int)(d_index/d_bits_per_chunk));
+ d_index = d_index%d_bits_per_chunk;
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_unpacked_to_packed_XX.h.t b/gnuradio-core/src/lib/general/gr_unpacked_to_packed_XX.h.t
new file mode 100644
index 0000000000..8d8c14d2a4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_unpacked_to_packed_XX.h.t
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_block.h>
+#include <gr_endianness.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @NAME@_sptr;
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness);
+
+/*!
+ * \brief Convert a stream of unpacked bytes or shorts into a stream of packed bytes or shorts.
+ * \ingroup block
+ *
+ * input: stream of @I_TYPE@; output: stream of @O_TYPE@
+ *
+ * This is the inverse of gr_packed_to_unpacked_XX.
+ *
+ * The low \p bits_per_chunk bits are extracted from each input byte or short.
+ * These bits are then packed densely into the output bytes or shorts, such that
+ * all 8 or 16 bits of the output bytes or shorts are filled with valid input bits.
+ * The right thing is done if bits_per_chunk is not a power of two.
+ *
+ * The combination of gr_packed_to_unpacked_XX followed by
+ * gr_chunks_to_symbols_Xf or gr_chunks_to_symbols_Xc handles the
+ * general case of mapping from a stream of bytes or shorts into arbitrary float
+ * or complex symbols.
+ *
+ * \sa gr_packed_to_unpacked_bb, gr_unpacked_to_packed_bb,
+ * \sa gr_packed_to_unpacked_ss, gr_unpacked_to_packed_ss,
+ * \sa gr_chunks_to_symbols_bf, gr_chunks_to_symbols_bc.
+ * \sa gr_chunks_to_symbols_sf, gr_chunks_to_symbols_sc.
+ */
+class @NAME@ : public gr_block
+{
+ friend @SPTR_NAME@
+ gr_make_@BASE_NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness);
+
+ @NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness);
+
+ unsigned int d_bits_per_chunk;
+ gr_endianness_t d_endianness;
+ unsigned int d_index;
+
+ public:
+ void forecast(int noutput_items, gr_vector_int &ninput_items_required);
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ bool check_topology(int ninputs, int noutputs) { return ninputs == noutputs; }
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_unpacked_to_packed_XX.i.t b/gnuradio-core/src/lib/general/gr_unpacked_to_packed_XX.i.t
new file mode 100644
index 0000000000..7fdcb5d7b6
--- /dev/null
+++ b/gnuradio-core/src/lib/general/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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness);
+
+class @NAME@ : public gr_block
+{
+ @NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness);
+};
diff --git a/gnuradio-core/src/lib/general/gr_vco.h b/gnuradio-core/src/lib/general/gr_vco.h
new file mode 100644
index 0000000000..3c35bdffe1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vco.h
@@ -0,0 +1,93 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _GR_VCO_H_
+#define _GR_VCO_H_
+
+
+#include <vector>
+#include <gr_sincos.h>
+#include <cmath>
+#include <gr_complex.h>
+
+/*!
+ * \brief base class template for Voltage Controlled Oscillator (VCO)
+ */
+
+//FIXME Eventually generalize this to fixed point
+
+template<class o_type, class i_type>
+class gr_vco {
+public:
+ gr_vco () : d_phase (0) {}
+
+ virtual ~gr_vco () {}
+
+ // radians
+ void set_phase (double angle) {
+ d_phase = angle;
+ }
+
+ void adjust_phase (double delta_phase) {
+ d_phase += delta_phase;
+ if (fabs (d_phase) > M_PI){
+
+ while (d_phase > M_PI)
+ d_phase -= 2*M_PI;
+
+ while (d_phase < -M_PI)
+ d_phase += 2*M_PI;
+ }
+ }
+
+ double get_phase () const { return d_phase; }
+
+ // compute sin and cos for current phase angle
+ void sincos (float *sinx, float *cosx) const;
+
+ // compute cos or sin for current phase angle
+ float cos () const { return std::cos (d_phase); }
+ float sin () const { return std::sin (d_phase); }
+
+ // compute a block at a time
+ void cos (float *output, const float *input, int noutput_items, double k, double ampl = 1.0);
+
+protected:
+ double d_phase;
+};
+
+template<class o_type, class i_type>
+void
+gr_vco<o_type,i_type>::sincos (float *sinx, float *cosx) const
+{
+ gr_sincosf (d_phase, sinx, cosx);
+}
+
+template<class o_type, class i_type>
+void
+gr_vco<o_type,i_type>::cos (float *output, const float *input, int noutput_items, double k, double ampl)
+{
+ for (int i = 0; i < noutput_items; i++){
+ output[i] = cos() * ampl;
+ adjust_phase(input[i] * k);
+ }
+}
+#endif /* _GR_VCO_H_ */
diff --git a/gnuradio-core/src/lib/general/gr_vco_f.cc b/gnuradio-core/src/lib/general/gr_vco_f.cc
new file mode 100644
index 0000000000..7421e4ec84
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vco_f.cc
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_vco_f.h>
+#include <gr_io_signature.h>
+#include <math.h>
+
+gr_vco_f_sptr
+gr_make_vco_f(double sampling_rate, double sensitivity, double amplitude)
+{
+ return gr_vco_f_sptr(new gr_vco_f(sampling_rate, sensitivity, amplitude));
+}
+
+
+gr_vco_f::gr_vco_f(double sampling_rate, double sensitivity, double amplitude)
+ : gr_sync_block("vco_f",
+ gr_make_io_signature(1, 1, sizeof(float)),
+ gr_make_io_signature(1, 1, sizeof(float))),
+ d_sampling_rate(sampling_rate), d_sensitivity(sensitivity), d_amplitude(amplitude),
+ d_k(d_sensitivity/d_sampling_rate)
+{
+}
+
+int
+gr_vco_f::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *input = (const float *)input_items[0];
+ float *output = (float *)output_items[0];
+
+ d_vco.cos(output, input, noutput_items, d_k, d_amplitude);
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_vco_f.h b/gnuradio-core/src/lib/general/gr_vco_f.h
new file mode 100644
index 0000000000..2872d38792
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vco_f.h
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_VCO_F_H
+#define INCLUDED_GR_VCO_F_H
+
+#include <gr_sync_block.h>
+#include <gr_fxpt_vco.h>
+
+class gr_vco_f;
+typedef boost::shared_ptr<gr_vco_f> gr_vco_f_sptr;
+
+/*!
+ * \brief VCO - Voltage controlled oscillator
+ *
+ * \param sampling_rate sampling rate (Hz)
+ * \param sensitivity units are radians/sec/volt
+ * \param amplitude output amplitude
+ */
+gr_vco_f_sptr gr_make_vco_f(double sampling_rate, double sensitivity, double amplitude);
+
+/*!
+ * \brief VCO - Voltage controlled oscillator
+ * \ingroup block
+ *
+ * input: float stream of control voltages; output: float oscillator output
+ */
+class gr_vco_f : public gr_sync_block
+{
+ friend gr_vco_f_sptr gr_make_vco_f(double sampling_rate, double sensitivity, double amplitude);
+
+ /*!
+ * \brief VCO - Voltage controlled oscillator
+ *
+ * \param sampling_rate sampling rate (Hz)
+ * \param sensitivity units are radians/sec/volt
+ * \param amplitude output amplitude
+ */
+ gr_vco_f(double sampling_rate, double sensitivity, double amplitude);
+
+ double d_sampling_rate;
+ double d_sensitivity;
+ double d_amplitude;
+ double d_k;
+ gr_fxpt_vco d_vco;
+
+public:
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_VCO_F_H */
diff --git a/gnuradio-core/src/lib/general/gr_vco_f.i b/gnuradio-core/src/lib/general/gr_vco_f.i
new file mode 100644
index 0000000000..d344745042
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,vco_f);
+
+/*!
+ * \brief VCO - Voltage controlled oscillator
+ *
+ * \param sampling_rate sampling rate (Hz)
+ * \param sensitivity units are radians/sec/volt
+ * \param amplitude output amplitude
+ */
+gr_vco_f_sptr gr_make_vco_f(double sampling_rate, double sensitivity, double amplitude);
+
+
+class gr_vco_f : public gr_sync_block {
+ private:
+ gr_vco_f(double sampling_rate, double sensitivity, double amplitude);
+};
diff --git a/gnuradio-core/src/lib/general/gr_vector_sink_X.cc.t b/gnuradio-core/src/lib/general/gr_vector_sink_X.cc.t
new file mode 100644
index 0000000000..5e99a92839
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vector_sink_X.cc.t
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <@NAME@.h>
+#include <algorithm>
+#include <gr_io_signature.h>
+
+
+@NAME@::@NAME@ ()
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof (@TYPE@)),
+ gr_make_io_signature (0, 0, 0))
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ @TYPE@ *iptr = (@TYPE@ *) input_items[0];
+ for (int i = 0; i < noutput_items; i++)
+ d_data.push_back (iptr[i]);
+
+ return noutput_items;
+}
+
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ ()
+{
+ return @NAME@_sptr (new @NAME@ ());
+}
+
+std::vector<@TYPE@>
+@NAME@::data () const
+{
+ return d_data;
+}
diff --git a/gnuradio-core/src/lib/general/gr_vector_sink_X.h.t b/gnuradio-core/src/lib/general/gr_vector_sink_X.h.t
new file mode 100644
index 0000000000..e549f1fbca
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vector_sink_X.h.t
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @NAME@_sptr;
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ ();
+
+
+/*!
+ * \brief @TYPE@ sink that writes to a vector
+ * \ingroup sink
+ */
+
+class @NAME@ : public gr_sync_block {
+ friend @NAME@_sptr gr_make_@BASE_NAME@ ();
+ std::vector<@TYPE@> d_data;
+ @NAME@ ();
+
+ public:
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ std::vector<@TYPE@> data () const;
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_vector_sink_X.i.t b/gnuradio-core/src/lib/general/gr_vector_sink_X.i.t
new file mode 100644
index 0000000000..d10636cfb4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vector_sink_X.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+class @NAME@ : public gr_sync_block {
+ private:
+ @NAME@ ();
+
+ public:
+ std::vector<@TYPE@> data () const;
+};
+
diff --git a/gnuradio-core/src/lib/general/gr_vector_source_X.cc.t b/gnuradio-core/src/lib/general/gr_vector_source_X.cc.t
new file mode 100644
index 0000000000..4ec2dd8bbc
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vector_source_X.cc.t
@@ -0,0 +1,85 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <@NAME@.h>
+#include <algorithm>
+#include <gr_io_signature.h>
+
+
+@NAME@::@NAME@ (const std::vector<@TYPE@> &data, bool repeat)
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (0, 0, 0),
+ gr_make_io_signature (1, 1, sizeof (@TYPE@))),
+ d_data (data),
+ d_repeat (repeat),
+ d_offset (0)
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ @TYPE@ *optr = (@TYPE@ *) output_items[0];
+
+ if (d_repeat){
+ unsigned int size = d_data.size ();
+ unsigned int offset = d_offset;
+
+ if (size == 0)
+ return -1;
+
+ for (int i = 0; i < noutput_items; i++){
+ optr[i] = d_data[offset++];
+ if (offset >= size)
+ offset = 0;
+ }
+ d_offset = offset;
+ return noutput_items;
+ }
+
+ else {
+ if (d_offset >= d_data.size ())
+ return -1; // Done!
+
+ unsigned n = std::min ((unsigned) d_data.size () - d_offset,
+ (unsigned) noutput_items);
+ for (unsigned i = 0; i < n; i++)
+ optr[i] = d_data[d_offset + i];
+
+ d_offset += n;
+ return n;
+ }
+}
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (const std::vector<@TYPE@> &data, bool repeat)
+{
+ return @NAME@_sptr (new @NAME@ (data, repeat));
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_vector_source_X.h.t b/gnuradio-core/src/lib/general/gr_vector_source_X.h.t
new file mode 100644
index 0000000000..631ab867c6
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vector_source_X.h.t
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @NAME@_sptr;
+
+/*!
+ * \brief source of @TYPE@'s that gets its data from a vector
+ * \ingroup source
+ */
+
+class @NAME@ : public gr_sync_block {
+ friend @NAME@_sptr
+ gr_make_@BASE_NAME@ (const std::vector<@TYPE@> &data, bool repeat = false);
+
+ std::vector<@TYPE@> d_data;
+ bool d_repeat;
+ unsigned int d_offset;
+
+ @NAME@ (const std::vector<@TYPE@> &data, bool repeat);
+
+ public:
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (const std::vector<@TYPE@> &data, bool repeat);
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_vector_source_X.i.t b/gnuradio-core/src/lib/general/gr_vector_source_X.i.t
new file mode 100644
index 0000000000..f3b98c62e7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vector_source_X.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (const std::vector<@TYPE@> &data, bool repeat = false);
+
+class @NAME@ : public gr_sync_block {
+ private:
+ @NAME@ (const std::vector<@TYPE@> &data);
+};
diff --git a/gnuradio-core/src/lib/general/gr_vector_to_stream.cc b/gnuradio-core/src/lib/general/gr_vector_to_stream.cc
new file mode 100644
index 0000000000..130f961322
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vector_to_stream.cc
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_vector_to_stream.h>
+#include <gr_io_signature.h>
+
+gr_vector_to_stream_sptr
+gr_make_vector_to_stream (size_t item_size, size_t nitems_per_block)
+{
+ return gr_vector_to_stream_sptr (new gr_vector_to_stream (item_size, nitems_per_block));
+}
+
+gr_vector_to_stream::gr_vector_to_stream (size_t item_size, size_t nitems_per_block)
+ : gr_sync_interpolator ("vector_to_stream",
+ gr_make_io_signature (1, 1, item_size * nitems_per_block),
+ gr_make_io_signature (1, 1, item_size),
+ nitems_per_block)
+{
+}
+
+int
+gr_vector_to_stream::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ size_t block_size = output_signature()->sizeof_stream_item (0);
+
+ const char *in = (const char *) input_items[0];
+ char *out = (char *) output_items[0];
+
+ memcpy (out, in, noutput_items * block_size);
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_vector_to_stream.h b/gnuradio-core/src/lib/general/gr_vector_to_stream.h
new file mode 100644
index 0000000000..5efff73301
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vector_to_stream.h
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_VECTOR_TO_STREAM_H
+#define INCLUDED_GR_VECTOR_TO_STREAM_H
+
+#include <gr_sync_interpolator.h>
+
+class gr_vector_to_stream;
+typedef boost::shared_ptr<gr_vector_to_stream> gr_vector_to_stream_sptr;
+
+gr_vector_to_stream_sptr
+gr_make_vector_to_stream (size_t item_size, size_t nitems_per_block);
+
+
+/*!
+ * \brief convert a stream of blocks of nitems_per_block items into a stream of items
+ * \ingroup block
+ */
+class gr_vector_to_stream : public gr_sync_interpolator
+{
+ friend gr_vector_to_stream_sptr
+ gr_make_vector_to_stream (size_t item_size, size_t nitems_per_block);
+
+ protected:
+ gr_vector_to_stream (size_t item_size, size_t nitems_per_block);
+
+ public:
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_VECTOR_TO_STREAM_H */
diff --git a/gnuradio-core/src/lib/general/gr_vector_to_stream.i b/gnuradio-core/src/lib/general/gr_vector_to_stream.i
new file mode 100644
index 0000000000..66ae1739ef
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,vector_to_stream)
+
+gr_vector_to_stream_sptr
+gr_make_vector_to_stream (size_t itemsize, size_t nitems_per_block);
+
+class gr_vector_to_stream : public gr_sync_decimator
+{
+ protected:
+ gr_vector_to_stream (size_t itemsize, size_t nitems_per_block);
+
+ public:
+};
diff --git a/gnuradio-core/src/lib/general/gr_vector_to_streams.cc b/gnuradio-core/src/lib/general/gr_vector_to_streams.cc
new file mode 100644
index 0000000000..4a3f110e04
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vector_to_streams.cc
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_vector_to_streams.h>
+#include <gr_io_signature.h>
+
+gr_vector_to_streams_sptr
+gr_make_vector_to_streams (size_t item_size, size_t nstreams)
+{
+ return gr_vector_to_streams_sptr (new gr_vector_to_streams (item_size, nstreams));
+}
+
+gr_vector_to_streams::gr_vector_to_streams (size_t item_size, size_t nstreams)
+ : gr_sync_block ("vector_to_streams",
+ gr_make_io_signature (1, 1, nstreams * item_size),
+ gr_make_io_signature (nstreams, nstreams, item_size))
+{
+}
+
+int
+gr_vector_to_streams::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ size_t item_size = output_signature()->sizeof_stream_item(0);
+ int nstreams = output_items.size();
+
+ const char *in = (const char *) input_items[0];
+ char **outv = (char **) &output_items[0];
+
+ for (int i = 0; i < noutput_items; i++){
+ for (int j = 0; j < nstreams; j++){
+ memcpy(outv[j], in, item_size);
+ outv[j] += item_size;
+ in += item_size;
+ }
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_vector_to_streams.h b/gnuradio-core/src/lib/general/gr_vector_to_streams.h
new file mode 100644
index 0000000000..ae13fae443
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vector_to_streams.h
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_VECTOR_TO_STREAMS_H
+#define INCLUDED_GR_VECTOR_TO_STREAMS_H
+
+#include <gr_sync_interpolator.h>
+
+class gr_vector_to_streams;
+typedef boost::shared_ptr<gr_vector_to_streams> gr_vector_to_streams_sptr;
+
+gr_vector_to_streams_sptr
+gr_make_vector_to_streams (size_t item_size, size_t nstreams);
+
+
+/*!
+ * \brief Convert 1 stream of vectors of length N to N streams of items
+ * \ingroup block
+ */
+class gr_vector_to_streams : public gr_sync_block
+{
+ friend gr_vector_to_streams_sptr
+ gr_make_vector_to_streams (size_t item_size, size_t nstreams);
+
+ protected:
+ gr_vector_to_streams (size_t item_size, size_t nstreams);
+
+ public:
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_VECTOR_TO_STREAMS_H */
diff --git a/gnuradio-core/src/lib/general/gr_vector_to_streams.i b/gnuradio-core/src/lib/general/gr_vector_to_streams.i
new file mode 100644
index 0000000000..7444d0d6f1
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,vector_to_streams)
+
+gr_vector_to_streams_sptr
+gr_make_vector_to_streams (size_t itemsize, size_t nstreams);
+
+class gr_vector_to_streams : public gr_sync_block
+{
+ protected:
+ gr_vector_to_streams (size_t itemsize, size_t nstreams);
+
+ public:
+};
diff --git a/gnuradio-core/src/lib/general/gri_add_const_ss.h b/gnuradio-core/src/lib/general/gri_add_const_ss.h
new file mode 100644
index 0000000000..49fddb68d2
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GRI_ADD_CONST_SS_H
+#define INCLUDED_GRI_ADD_CONST_SS_H
+
+/*!
+ * \brief Low-level, high-speed add_const_ss primitive
+ *
+ * copy src to dst adding konst
+ */
+
+void
+gri_add_const_ss (short *dst, const short *src, int nshorts, short konst);
+
+
+#endif /* _INCLUDED_GRI_ADD_CONST_SS_H_ */
diff --git a/gnuradio-core/src/lib/general/gri_add_const_ss_generic.cc b/gnuradio-core/src/lib/general/gri_add_const_ss_generic.cc
new file mode 100644
index 0000000000..f94db30e98
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_add_const_ss.h>
+
+void
+gri_add_const_ss (short *dst, const short *src, int nshorts, short konst)
+{
+ static const int STRIDE = 8;
+
+ int i;
+
+ for (i = 0; i < nshorts - (STRIDE - 1); i += STRIDE){
+ dst[i + 0] = src[i + 0] + konst;
+ dst[i + 1] = src[i + 1] + konst;
+ dst[i + 2] = src[i + 2] + konst;
+ dst[i + 3] = src[i + 3] + konst;
+ dst[i + 4] = src[i + 4] + konst;
+ dst[i + 5] = src[i + 5] + konst;
+ dst[i + 6] = src[i + 6] + konst;
+ dst[i + 7] = src[i + 7] + konst;
+ }
+
+ for (; i < nshorts; i++)
+ dst[i] = src[i] + konst;
+}
diff --git a/gnuradio-core/src/lib/general/gri_agc.h b/gnuradio-core/src/lib/general/gri_agc.h
new file mode 100644
index 0000000000..eaaed8c3e8
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_agc.h
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GRI_AGC_H_
+#define _GRI_AGC_H_
+
+#include <math.h>
+
+/*!
+ * \brief high performance Automatic Gain Control class
+ *
+ * Power is approximated by absolute value
+ */
+
+class gri_agc {
+
+ public:
+ gri_agc (float rate = 1e-4, float reference = 1.0, float gain = 1.0, float max_gain = 0.0)
+ : _rate(rate), _reference(reference), _gain(gain), _max_gain(max_gain) {};
+
+ float rate () const { return _rate; }
+ float reference () const { return _reference; }
+ float gain () const { return _gain; }
+ float max_gain () const { return _max_gain; }
+
+ void set_rate (float rate) { _rate = rate; }
+ void set_reference (float reference) { _reference = reference; }
+ void set_gain (float gain) { _gain = gain; }
+ void set_max_gain (float max_gain) { _max_gain = max_gain; }
+
+ float scale (float input){
+ float output = input * _gain;
+ _gain += (_reference - fabsf (output)) * _rate;
+ if (_max_gain > 0.0 && _gain > _max_gain)
+ _gain = _max_gain;
+ return output;
+ }
+
+ void scaleN (float output[], const float input[], unsigned n){
+ for (unsigned i = 0; i < n; i++)
+ output[i] = scale (input[i]);
+ }
+
+ protected:
+ float _rate; // adjustment rate
+ float _reference; // reference value
+ float _gain; // current gain
+ float _max_gain; // maximum gain
+};
+
+#endif /* _GRI_AGC_H_ */
diff --git a/gnuradio-core/src/lib/general/gri_agc.i b/gnuradio-core/src/lib/general/gri_agc.i
new file mode 100644
index 0000000000..0bdbd40443
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_agc.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <math.h>
+
+/*!
+ * \brief high performance Automatic Gain Control class
+ *
+ * Power is approximated by absolute value
+ */
+
+
+class gri_agc {
+
+ public:
+ gri_agc (float rate = 1e-4, float reference = 1.0, float gain = 1.0, float max_gain = 0.0);
+ };
diff --git a/gnuradio-core/src/lib/general/gri_agc_cc.h b/gnuradio-core/src/lib/general/gri_agc_cc.h
new file mode 100644
index 0000000000..5cdd4e4657
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_agc_cc.h
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GRI_AGC_CC_H_
+#define _GRI_AGC_CC_H_
+
+#include <math.h>
+
+/*!
+ * \brief high performance Automatic Gain Control class
+ *
+ * For Power the absolute value of the complex number is used.
+ */
+
+class gri_agc_cc {
+
+ public:
+ gri_agc_cc (float rate = 1e-4, float reference = 1.0, float gain = 1.0, float max_gain = 0.0)
+ : _rate(rate), _reference(reference), _gain(gain), _max_gain(max_gain) {};
+
+ float rate () const { return _rate; }
+ float reference () const { return _reference; }
+ float gain () const { return _gain; }
+ float max_gain() const { return _max_gain; }
+
+ void set_rate (float rate) { _rate = rate; }
+ void set_reference (float reference) { _reference = reference; }
+ void set_gain (float gain) { _gain = gain; }
+ void set_max_gain(float max_gain) { _max_gain = max_gain; }
+
+ gr_complex scale (gr_complex input){
+ gr_complex output = input * _gain;
+ _gain += (_reference - sqrt(output.real()*output.real()+output.imag()*output.imag())) * _rate; //use abs or cabs to get approximation by absolute value,
+ //note that abs is computationally more intensive then norm for a complex number
+ if (_max_gain > 0.0 && _gain > _max_gain)
+ _gain = _max_gain;
+ return output;
+ }
+
+ void scaleN (gr_complex output[], const gr_complex input[], unsigned n){
+ for (unsigned i = 0; i < n; i++)
+ output[i] = scale (input[i]);
+ }
+
+ protected:
+ float _rate; // adjustment rate
+ float _reference; // reference value
+ float _gain; // current gain
+ float _max_gain; // max allowable gain
+};
+
+#endif /* _GRI_AGC_CC_H_ */
diff --git a/gnuradio-core/src/lib/general/gri_agc_cc.i b/gnuradio-core/src/lib/general/gri_agc_cc.i
new file mode 100644
index 0000000000..70c1baa7b6
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_agc_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <math.h>
+
+/*!
+ * \brief high performance Automatic Gain Control class
+ *
+ * For Power the absolute value of the complex number is used.
+ */
+
+
+class gri_agc_cc {
+
+ public:
+ gri_agc_cc (float rate = 1e-4, float reference = 1.0, float gain = 1.0, float max_gain = 0.0);
+ float rate ();
+ float reference ();
+ float gain ();
+ float max_gain ();
+ };
diff --git a/gnuradio-core/src/lib/general/gri_char_to_float.cc b/gnuradio-core/src/lib/general/gri_char_to_float.cc
new file mode 100644
index 0000000000..ca02ca27cd
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gri_char_to_float.h>
+
+void
+gri_char_to_float (const char *in, float *out, int nsamples)
+{
+ while (nsamples >= 4){
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out[3] = in[3];
+ out += 4;
+ in += 4;
+ nsamples -= 4;
+ }
+
+ while (nsamples-- > 0)
+ *out++ = *in++;
+}
diff --git a/gnuradio-core/src/lib/general/gri_char_to_float.h b/gnuradio-core/src/lib/general/gri_char_to_float.h
new file mode 100644
index 0000000000..7aa38d0204
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_char_to_float.h
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GRI_CHAR_TO_FLOAT_H
+#define INCLUDED_GRI_CHAR_TO_FLOAT_H
+
+/*
+ * convert array of chars to floats
+ */
+void gri_char_to_float (const char *in, float *out, int nsamples);
+
+
+#endif /* INCLUDED_GRI_CHAR_TO_FLOAT_H */
diff --git a/gnuradio-core/src/lib/general/gri_debugger_hook.cc b/gnuradio-core/src/lib/general/gri_debugger_hook.cc
new file mode 100644
index 0000000000..35e138aa23
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gri_debugger_hook.h>
+
+void
+gri_debugger_hook ()
+{
+ // nop. set a breakpoint here
+}
diff --git a/gnuradio-core/src/lib/general/gri_debugger_hook.h b/gnuradio-core/src/lib/general/gri_debugger_hook.h
new file mode 100644
index 0000000000..612b7c59bb
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_debugger_hook.h
@@ -0,0 +1,28 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GRI_DEBUGGER_HOOK_H
+#define INCLUDED_GRI_DEBUGGER_HOOK_H
+
+void gri_debugger_hook ();
+
+#endif /* INCLUDED_GRI_DEBUGGER_HOOK_H */
diff --git a/gnuradio-core/src/lib/general/gri_fft.cc b/gnuradio-core/src/lib/general/gri_fft.cc
new file mode 100644
index 0000000000..30b012716d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_fft.cc
@@ -0,0 +1,229 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gri_fft.h>
+#include <fftw3.h>
+#include <gr_complex.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <cassert>
+#include <stdexcept>
+
+static char *
+wisdom_filename ()
+{
+ static char *filename = ".gr_fftw_wisdom";
+
+ char *home = getenv ("HOME");
+ if (home){
+ char *p = new char[strlen (home) + strlen (filename) + 2];
+ strcpy (p, home);
+ strcat (p, "/");
+ strcat (p, filename);
+ return p;
+ }
+ return 0;
+}
+
+static void
+gri_fftw_import_wisdom ()
+{
+ char *filename = wisdom_filename ();
+ FILE *fp = fopen (filename, "r");
+ if (fp != 0){
+ int r = fftwf_import_wisdom_from_file (fp);
+ fclose (fp);
+ if (!r){
+ fprintf (stderr, "gri_fftw: can't import wisdom from %s\n", filename);
+ }
+ }
+ delete [] filename;
+}
+
+static void
+gri_fftw_export_wisdom ()
+{
+ char *filename = wisdom_filename ();
+ FILE *fp = fopen (filename, "w");
+ if (fp != 0){
+ fftwf_export_wisdom_to_file (fp);
+ fclose (fp);
+ }
+ else {
+ fprintf (stderr, "gri_fftw: ");
+ perror (filename);
+ }
+ delete [] filename;
+}
+
+// ----------------------------------------------------------------
+
+gri_fft_complex::gri_fft_complex (int fft_size, bool forward)
+{
+ assert (sizeof (fftwf_complex) == sizeof (gr_complex));
+
+ if (fft_size <= 0)
+ throw std::out_of_range ("gri_fftw: invalid fft_size");
+
+ d_fft_size = fft_size;
+ d_inbuf = (gr_complex *) fftwf_malloc (sizeof (gr_complex) * inbuf_length ());
+ if (d_inbuf == 0)
+ throw std::runtime_error ("fftwf_malloc");
+
+ d_outbuf = (gr_complex *) fftwf_malloc (sizeof (gr_complex) * outbuf_length ());
+ if (d_outbuf == 0){
+ fftwf_free (d_inbuf);
+ throw std::runtime_error ("fftwf_malloc");
+ }
+
+ // FIXME If there's ever a chance that the planning functions
+ // will be called in multiple threads, we've got to ensure single
+ // threaded access. They are not thread-safe.
+
+ gri_fftw_import_wisdom (); // load prior wisdom from disk
+ d_plan = fftwf_plan_dft_1d (fft_size,
+ reinterpret_cast<fftwf_complex *>(d_inbuf),
+ reinterpret_cast<fftwf_complex *>(d_outbuf),
+ forward ? FFTW_FORWARD : FFTW_BACKWARD,
+ FFTW_MEASURE);
+
+ if (d_plan == NULL) {
+ fprintf(stderr, "gri_fft_complex: error creating plan\n");
+ throw std::runtime_error ("fftwf_plan_dft_1d failed");
+ }
+ gri_fftw_export_wisdom (); // store new wisdom to disk
+}
+
+gri_fft_complex::~gri_fft_complex ()
+{
+ fftwf_destroy_plan ((fftwf_plan) d_plan);
+ fftwf_free (d_inbuf);
+ fftwf_free (d_outbuf);
+}
+
+void
+gri_fft_complex::execute ()
+{
+ fftwf_execute ((fftwf_plan) d_plan);
+}
+
+// ----------------------------------------------------------------
+
+gri_fft_real_fwd::gri_fft_real_fwd (int fft_size)
+{
+ assert (sizeof (fftwf_complex) == sizeof (gr_complex));
+
+ if (fft_size <= 0)
+ throw std::out_of_range ("gri_fftw: invalid fft_size");
+
+ d_fft_size = fft_size;
+ d_inbuf = (float *) fftwf_malloc (sizeof (float) * inbuf_length ());
+ if (d_inbuf == 0)
+ throw std::runtime_error ("fftwf_malloc");
+
+ d_outbuf = (gr_complex *) fftwf_malloc (sizeof (gr_complex) * outbuf_length ());
+ if (d_outbuf == 0){
+ fftwf_free (d_inbuf);
+ throw std::runtime_error ("fftwf_malloc");
+ }
+
+ // FIXME If there's ever a chance that the planning functions
+ // will be called in multiple threads, we've got to ensure single
+ // threaded access. They are not thread-safe.
+
+ gri_fftw_import_wisdom (); // load prior wisdom from disk
+ d_plan = fftwf_plan_dft_r2c_1d (fft_size,
+ d_inbuf,
+ reinterpret_cast<fftwf_complex *>(d_outbuf),
+ FFTW_MEASURE);
+
+ if (d_plan == NULL) {
+ fprintf(stderr, "gri_fft_real_fwd: error creating plan\n");
+ throw std::runtime_error ("fftwf_plan_dft_r2c_1d failed");
+ }
+ gri_fftw_export_wisdom (); // store new wisdom to disk
+}
+
+gri_fft_real_fwd::~gri_fft_real_fwd ()
+{
+ fftwf_destroy_plan ((fftwf_plan) d_plan);
+ fftwf_free (d_inbuf);
+ fftwf_free (d_outbuf);
+}
+
+void
+gri_fft_real_fwd::execute ()
+{
+ fftwf_execute ((fftwf_plan) d_plan);
+}
+
+// ----------------------------------------------------------------
+
+gri_fft_real_rev::gri_fft_real_rev (int fft_size)
+{
+ assert (sizeof (fftwf_complex) == sizeof (gr_complex));
+
+ if (fft_size <= 0)
+ throw std::out_of_range ("gri_fftw: invalid fft_size");
+
+ d_fft_size = fft_size;
+ d_inbuf = (gr_complex *) fftwf_malloc (sizeof (gr_complex) * inbuf_length ());
+ if (d_inbuf == 0)
+ throw std::runtime_error ("fftwf_malloc");
+
+ d_outbuf = (float *) fftwf_malloc (sizeof (float) * outbuf_length ());
+ if (d_outbuf == 0){
+ fftwf_free (d_inbuf);
+ throw std::runtime_error ("fftwf_malloc");
+ }
+
+ // FIXME If there's ever a chance that the planning functions
+ // will be called in multiple threads, we've got to ensure single
+ // threaded access. They are not thread-safe.
+
+ gri_fftw_import_wisdom (); // load prior wisdom from disk
+ d_plan = fftwf_plan_dft_c2r_1d (fft_size,
+ reinterpret_cast<fftwf_complex *>(d_inbuf),
+ d_outbuf,
+ FFTW_MEASURE);
+
+ if (d_plan == NULL) {
+ fprintf(stderr, "gri_fft_real_rev: error creating plan\n");
+ throw std::runtime_error ("fftwf_plan_dft_c2r_1d failed");
+ }
+ gri_fftw_export_wisdom (); // store new wisdom to disk
+}
+
+gri_fft_real_rev::~gri_fft_real_rev ()
+{
+ fftwf_destroy_plan ((fftwf_plan) d_plan);
+ fftwf_free (d_inbuf);
+ fftwf_free (d_outbuf);
+}
+
+void
+gri_fft_real_rev::execute ()
+{
+ fftwf_execute ((fftwf_plan) d_plan);
+}
+
diff --git a/gnuradio-core/src/lib/general/gri_fft.h b/gnuradio-core/src/lib/general/gri_fft.h
new file mode 100644
index 0000000000..5034774845
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_fft.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _GRI_FFT_H_
+#define _GRI_FFT_H_
+
+/*
+ * Wrappers for FFTW single precision 1d dft
+ */
+
+#include <gr_complex.h>
+
+/*!
+ * \brief FFT: complex in, complex out
+ */
+
+class gri_fft_complex {
+ int d_fft_size;
+ gr_complex *d_inbuf;
+ gr_complex *d_outbuf;
+ void *d_plan;
+
+public:
+ gri_fft_complex (int fft_size, bool forward = true);
+ virtual ~gri_fft_complex ();
+
+ /*
+ * These return pointers to buffers owned by gri_fft_complex into which
+ * input and output take place. It's done this way in order to
+ * ensure optimal alignment for SIMD instructions.
+ */
+ gr_complex *get_inbuf () const { return d_inbuf; }
+ gr_complex *get_outbuf () const { return d_outbuf; }
+
+ int inbuf_length () const { return d_fft_size; }
+ int outbuf_length () const { return d_fft_size; }
+
+ /*!
+ * compute FFT. The input comes from inbuf, the output is placed in outbuf.
+ */
+ void execute ();
+};
+
+/*!
+ * \brief FFT: real in, complex out
+ */
+class gri_fft_real_fwd {
+ int d_fft_size;
+ float *d_inbuf;
+ gr_complex *d_outbuf;
+ void *d_plan;
+
+public:
+ gri_fft_real_fwd (int fft_size);
+ virtual ~gri_fft_real_fwd ();
+
+ /*
+ * These return pointers to buffers owned by gri_fft_real_fwd into
+ * which input and output take place. It's done this way in order
+ * to ensure optimal alignment for SIMD instructions.
+ */
+ float *get_inbuf () const { return d_inbuf; }
+ gr_complex *get_outbuf () const { return d_outbuf; }
+
+ int inbuf_length () const { return d_fft_size; }
+ int outbuf_length () const { return d_fft_size / 2 + 1; }
+
+ /*!
+ * compute FFT. The input comes from inbuf, the output is placed in outbuf.
+ */
+ void execute ();
+};
+
+/*!
+ * \brief FFT: complex in, float out
+ */
+class gri_fft_real_rev {
+ int d_fft_size;
+ gr_complex *d_inbuf;
+ float *d_outbuf;
+ void *d_plan;
+
+public:
+ gri_fft_real_rev (int fft_size);
+ virtual ~gri_fft_real_rev ();
+
+ /*
+ * These return pointers to buffers owned by gri_fft_real_rev into
+ * which input and output take place. It's done this way in order
+ * to ensure optimal alignment for SIMD instructions.
+ */
+ gr_complex *get_inbuf () const { return d_inbuf; }
+ float *get_outbuf () const { return d_outbuf; }
+
+ int inbuf_length () const { return d_fft_size / 2 + 1; }
+ int outbuf_length () const { return d_fft_size; }
+
+ /*!
+ * compute FFT. The input comes from inbuf, the output is placed in outbuf.
+ */
+ void execute ();
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gri_float_to_char.cc b/gnuradio-core/src/lib/general/gri_float_to_char.cc
new file mode 100644
index 0000000000..b94c53442a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_float_to_char.cc
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#define _ISOC9X_SOURCE
+#include <gri_float_to_char.h>
+#include <math.h>
+
+static const int MIN_CHAR = -128;
+static const int MAX_CHAR = 127;
+
+
+void
+gri_float_to_char (const float *in, char *out, int nsamples)
+{
+ for (int i = 0; i < nsamples; i++){
+ long int r = (long int) rint (in[i]);
+ if (r < MIN_CHAR)
+ r = MIN_CHAR;
+ else if (r > MAX_CHAR)
+ r = MAX_CHAR;
+ out[i] = r;
+ }
+}
diff --git a/gnuradio-core/src/lib/general/gri_float_to_char.h b/gnuradio-core/src/lib/general/gri_float_to_char.h
new file mode 100644
index 0000000000..8891ac1abd
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_float_to_char.h
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GRI_FLOAT_TO_CHAR_H
+#define INCLUDED_GRI_FLOAT_TO_CHAR_H
+
+/*!
+ * convert array of floats to chars with rounding and saturation.
+ */
+void gri_float_to_char (const float *in, char *out, int nsamples);
+
+#endif /* INCLUDED_GRI_FLOAT_TO_CHAR_H */
+
diff --git a/gnuradio-core/src/lib/general/gri_float_to_short.cc b/gnuradio-core/src/lib/general/gri_float_to_short.cc
new file mode 100644
index 0000000000..b2910616c9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_float_to_short.cc
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#define _ISOC9X_SOURCE
+#include <gri_float_to_short.h>
+#include <math.h>
+
+static const int MIN_SHORT = -32768;
+static const int MAX_SHORT = 32767;
+
+
+void
+gri_float_to_short (const float *in, short *out, int nsamples)
+{
+ for (int i = 0; i < nsamples; i++){
+ long int r = (long int) rint (in[i]);
+ if (r < MIN_SHORT)
+ r = MIN_SHORT;
+ else if (r > MAX_SHORT)
+ r = MAX_SHORT;
+ out[i] = r;
+ }
+}
diff --git a/gnuradio-core/src/lib/general/gri_float_to_short.h b/gnuradio-core/src/lib/general/gri_float_to_short.h
new file mode 100644
index 0000000000..e13b61d5d9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_float_to_short.h
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GRI_FLOAT_TO_SHORT_H
+#define INCLUDED_GRI_FLOAT_TO_SHORT_H
+
+/*!
+ * convert array of floats to shorts with rounding and saturation.
+ */
+void gri_float_to_short (const float *in, short *out, int nsamples);
+
+#endif /* INCLUDED_GRI_FLOAT_TO_SHORT_H */
+
diff --git a/gnuradio-core/src/lib/general/gri_float_to_uchar.cc b/gnuradio-core/src/lib/general/gri_float_to_uchar.cc
new file mode 100644
index 0000000000..8281a967e3
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_float_to_uchar.cc
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#define _ISOC9X_SOURCE
+#include <gri_float_to_uchar.h>
+#include <math.h>
+
+static const int MIN_UCHAR = 0;
+static const int MAX_UCHAR = 255;
+
+
+void
+gri_float_to_uchar (const float *in, unsigned char *out, int nsamples)
+{
+ for (int i = 0; i < nsamples; i++){
+ long int r = (long int) rint (in[i]);
+ if (r < MIN_UCHAR)
+ r = MIN_UCHAR;
+ else if (r > MAX_UCHAR)
+ r = MAX_UCHAR;
+ out[i] = r;
+ }
+}
diff --git a/gnuradio-core/src/lib/general/gri_float_to_uchar.h b/gnuradio-core/src/lib/general/gri_float_to_uchar.h
new file mode 100644
index 0000000000..fbde8c51a3
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_float_to_uchar.h
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GRI_FLOAT_TO_UCHAR_H
+#define INCLUDED_GRI_FLOAT_TO_UCHAR_H
+
+/*!
+ * convert array of floats to unsigned chars with rounding and saturation.
+ */
+void gri_float_to_uchar (const float *in, unsigned char *out, int nsamples);
+
+#endif /* INCLUDED_GRI_FLOAT_TO_UCHAR_H */
+
diff --git a/gnuradio-core/src/lib/general/gri_interleaved_short_to_complex.cc b/gnuradio-core/src/lib/general/gri_interleaved_short_to_complex.cc
new file mode 100644
index 0000000000..56e3c39a56
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_interleaved_short_to_complex.h>
+#include <assert.h>
+
+void
+gri_interleaved_short_to_complex (const short *in,
+ gr_complex *out, int nsamples)
+{
+ assert (nsamples % 2 == 0);
+
+ for (int i = 0; i < nsamples/2; i++){
+ out[i] = gr_complex (in[i*2 + 0], in[i*2 + 1]);
+ }
+}
diff --git a/gnuradio-core/src/lib/general/gri_interleaved_short_to_complex.h b/gnuradio-core/src/lib/general/gri_interleaved_short_to_complex.h
new file mode 100644
index 0000000000..3a0fc3de6b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_interleaved_short_to_complex.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GRI_INTERLEAVED_SHORT_TO_COMPLEX_H
+#define INCLUDED_GRI_INTERLEAVED_SHORT_TO_COMPLEX_H
+
+#include <gr_complex.h>
+
+/*
+ * convert array of interleaved shorts to complex.
+ * the shorts contains real, imaginary, real, imaginary...
+ * nsamples is the number of shorts; it must be even.
+ */
+void gri_interleaved_short_to_complex (const short *in, gr_complex *out, int nsamples);
+
+#endif /* INCLUDED_GRI_INTERLEAVED_SHORT_TO_COMPLEX_H */
+
+
diff --git a/gnuradio-core/src/lib/general/gri_lfsr_15_1_0.h b/gnuradio-core/src/lib/general/gri_lfsr_15_1_0.h
new file mode 100644
index 0000000000..561ba6c525
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_lfsr_15_1_0.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GRI_LFSR_15_1_0_H
+#define INCLUDED_GRI_LFSR_15_1_0_H
+
+/*!
+ * \brief Linear Feedback Shift Register using primitive polynomial x^15 + x + 1
+ *
+ * Generates a maximal length pseudo-random sequence of length 2^15 - 1 bits.
+ */
+
+class gri_lfsr_15_1_0 {
+ unsigned long d_sr; // shift register
+
+ public:
+
+ gri_lfsr_15_1_0 () { reset (); }
+
+ void reset () { d_sr = 0x7fff; }
+
+ int next_bit (){
+ d_sr = ((((d_sr >> 1) ^ d_sr) & 0x1) << 14) | (d_sr >> 1);
+ return d_sr & 0x1;
+ }
+
+ int next_byte (){
+ int v = 0;
+ for (int i = 0; i < 8; i++){
+ v >>= 1;
+ if (next_bit ())
+ v |= 0x80;
+ }
+ return v;
+ }
+};
+
+#endif /* INCLUDED_GRI_LFSR_15_1_0_H */
diff --git a/gnuradio-core/src/lib/general/gri_lfsr_32k.h b/gnuradio-core/src/lib/general/gri_lfsr_32k.h
new file mode 100644
index 0000000000..653223e671
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_lfsr_32k.h
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GRI_LFSR_32k_H
+#define INCLUDED_GRI_LFSR_32k_H
+
+#include <gri_lfsr_15_1_0.h>
+
+/*!
+ * \brief generate pseudo-random sequence of length 32768 bits.
+ *
+ * This is based on gri_lfsr_15_1_0 with an extra 0 added at the end
+ * of the sequence.
+ */
+
+class gri_lfsr_32k {
+ gri_lfsr_15_1_0 d_lfsr;
+ unsigned int d_count;
+
+ public:
+ gri_lfsr_32k () { reset (); }
+
+ void reset (){
+ d_lfsr.reset ();
+ d_count = 0;
+ }
+
+ int next_bit (){
+ if (d_count == 32767){
+ d_count = 0;
+ return 0;
+ }
+ d_count++;
+ return d_lfsr.next_bit ();
+ }
+
+ int next_byte (){
+ int v = 0;
+ for (int i = 0; i < 8; i++){
+ v >>= 1;
+ if (next_bit ())
+ v |= 0x80;
+ }
+ return v;
+ }
+
+ int next_short (){
+ int v = 0;
+ for (int i = 0; i < 16; i++){
+ v >>= 1;
+ if (next_bit ())
+ v |= 0x8000;
+ }
+ return v;
+ }
+
+};
+
+#endif /* INCLUDED_GRI_LFSR_32k_H */
diff --git a/gnuradio-core/src/lib/general/gri_short_to_float.cc b/gnuradio-core/src/lib/general/gri_short_to_float.cc
new file mode 100644
index 0000000000..f6beb45605
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gri_short_to_float.h>
+
+void
+gri_short_to_float (const short *in, float *out, int nsamples)
+{
+ while (nsamples >= 4){
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out[3] = in[3];
+ out += 4;
+ in += 4;
+ nsamples -= 4;
+ }
+
+ while (nsamples-- > 0)
+ *out++ = *in++;
+}
diff --git a/gnuradio-core/src/lib/general/gri_short_to_float.h b/gnuradio-core/src/lib/general/gri_short_to_float.h
new file mode 100644
index 0000000000..1abd0dd549
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_short_to_float.h
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GRI_SHORT_TO_FLOAT_H
+#define INCLUDED_GRI_SHORT_TO_FLOAT_H
+
+/*
+ * convert array of shorts to floats
+ */
+void gri_short_to_float (const short *in, float *out, int nsamples);
+
+
+#endif /* INCLUDED_GRI_SHORT_TO_FLOAT_H */
diff --git a/gnuradio-core/src/lib/general/gri_uchar_to_float.cc b/gnuradio-core/src/lib/general/gri_uchar_to_float.cc
new file mode 100644
index 0000000000..8a5f87a564
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gri_uchar_to_float.h>
+
+void
+gri_uchar_to_float (const unsigned char *in, float *out, int nsamples)
+{
+ while (nsamples >= 4){
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out[3] = in[3];
+ out += 4;
+ in += 4;
+ nsamples -= 4;
+ }
+
+ while (nsamples-- > 0)
+ *out++ = *in++;
+}
diff --git a/gnuradio-core/src/lib/general/gri_uchar_to_float.h b/gnuradio-core/src/lib/general/gri_uchar_to_float.h
new file mode 100644
index 0000000000..50646e46e2
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_uchar_to_float.h
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GRI_UCHAR_TO_FLOAT_H
+#define INCLUDED_GRI_UCHAR_TO_FLOAT_H
+
+/*
+ * convert array of unsigned chars to floats
+ */
+void gri_uchar_to_float (const unsigned char *in, float *out, int nsamples);
+
+
+#endif /* INCLUDED_GRI_UCHAR_TO_FLOAT_H */
diff --git a/gnuradio-core/src/lib/general/malloc16.c b/gnuradio-core/src/lib/general/malloc16.c
new file mode 100644
index 0000000000..2cc6135e77
--- /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 0000000000..0376ec567e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/malloc16.h
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+
+void *malloc16Align(int size);
+void *calloc16Align(size_t nmemb,size_t size);
+void free16Align(void *p);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/gnuradio-core/src/lib/general/qa_general.cc b/gnuradio-core/src/lib/general/qa_general.cc
new file mode 100644
index 0000000000..1fa2b93580
--- /dev/null
+++ b/gnuradio-core/src/lib/general/qa_general.cc
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * This class gathers together all the test cases for the gr
+ * directory into a single test suite. As you create new test cases,
+ * add them here.
+ */
+
+#include <qa_general.h>
+#include <qa_gr_firdes.h>
+#include <qa_gr_circular_file.h>
+#include <qa_gr_fxpt.h>
+#include <qa_gr_fxpt_nco.h>
+#include <qa_gr_fxpt_vco.h>
+
+CppUnit::TestSuite *
+qa_general::suite ()
+{
+ CppUnit::TestSuite *s = new CppUnit::TestSuite ("general");
+
+ s->addTest (qa_gr_firdes::suite ());
+ s->addTest (qa_gr_circular_file::suite ());
+ s->addTest (qa_gr_fxpt::suite ());
+ s->addTest (qa_gr_fxpt_nco::suite ());
+ s->addTest (qa_gr_fxpt_vco::suite ());
+
+ return s;
+}
diff --git a/gnuradio-core/src/lib/general/qa_general.h b/gnuradio-core/src/lib/general/qa_general.h
new file mode 100644
index 0000000000..6bf57df67a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/qa_general.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _QA_GENERAL_H_
+#define _QA_GENERAL_H_
+
+#include <cppunit/TestSuite.h>
+
+//! collect all the tests for the gr directory
+
+class qa_general {
+ public:
+ //! return suite of tests for all of gr directory
+ static CppUnit::TestSuite *suite ();
+};
+
+
+#endif /* _QA_GENERAL_H_ */
diff --git a/gnuradio-core/src/lib/general/qa_gr_circular_file.cc b/gnuradio-core/src/lib/general/qa_gr_circular_file.cc
new file mode 100644
index 0000000000..adfa33cb4d
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <qa_gr_circular_file.h>
+#include <gr_circular_file.h>
+#include <cppunit/TestAssert.h>
+#include <iostream>
+#include <stdio.h>
+#include <unistd.h>
+
+static const char *test_file = "qa_gr_circular_file.data";
+static const int BUFFER_SIZE = 8192;
+static const int NWRITE = 8192 * 9 / 8;
+
+void
+qa_gr_circular_file::t1 ()
+{
+#ifdef HAVE_MMAP
+ gr_circular_file *cf_writer;
+ gr_circular_file *cf_reader;
+
+ // write the data...
+
+ cf_writer = new gr_circular_file (test_file, true, BUFFER_SIZE * sizeof (short));
+
+ short sd;
+ for (int i = 0; i < NWRITE; i++){
+ sd = i;
+ cf_writer->write (&sd, sizeof (sd));
+ }
+
+ delete cf_writer;
+
+ // now read it back...
+
+ cf_reader = new gr_circular_file (test_file);
+ for (int i = 0; i < BUFFER_SIZE; i++){
+ int n = cf_reader->read (&sd, sizeof (sd));
+ CPPUNIT_ASSERT_EQUAL ((int) sizeof (sd), n);
+ CPPUNIT_ASSERT_EQUAL (NWRITE - BUFFER_SIZE + i, (int) sd);
+ }
+
+ int n = cf_reader->read (&sd, sizeof (sd));
+ CPPUNIT_ASSERT_EQUAL (0, n);
+
+ delete cf_reader;
+ unlink (test_file);
+#endif // HAVE_MMAP
+}
+
diff --git a/gnuradio-core/src/lib/general/qa_gr_circular_file.h b/gnuradio-core/src/lib/general/qa_gr_circular_file.h
new file mode 100644
index 0000000000..45ebfd8e12
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _QA_GR_CIRCULAR_FILE_H_
+#define _QA_GR_CIRCULAR_FILE_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_circular_file : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gr_circular_file);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void t1 ();
+
+};
+
+
+#endif /* _QA_GR_CIRCULAR_FILE_H_ */
diff --git a/gnuradio-core/src/lib/general/qa_gr_firdes.cc b/gnuradio-core/src/lib/general/qa_gr_firdes.cc
new file mode 100644
index 0000000000..072bcb6807
--- /dev/null
+++ b/gnuradio-core/src/lib/general/qa_gr_firdes.cc
@@ -0,0 +1,344 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <qa_gr_firdes.h>
+#include <gr_firdes.h>
+#include <cppunit/TestAssert.h>
+#include <gr_complex.h>
+#include <string.h>
+#include <iostream>
+#include <iomanip>
+#include <stdio.h>
+
+#define NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+using std::vector;
+
+static void
+print_taps (std::ostream &s, vector<float> &v)
+{
+
+ for (unsigned int i = 0; i < v.size (); i++){
+ printf ("tap[%2d] = %16.7e\n", i, v[i]);
+ }
+}
+
+static void
+check_symmetry (vector<float> &v)
+{
+ int n = v.size ();
+ int m = n / 2;
+
+ for (int i = 0; i < m; i++)
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (v[i], v[n - i - 1], 1e-9);
+}
+
+const static float t1_exp[53] = {
+ -9.0525491e-04,
+ 2.0713841e-04,
+ 1.2388536e-03,
+ 2.9683491e-04,
+ -1.7744775e-03,
+ -1.3599906e-03,
+ 2.2031884e-03,
+ 3.2744040e-03,
+ -1.8868084e-03,
+ -5.9935520e-03,
+ 6.4301129e-18,
+ 8.9516686e-03,
+ 4.2178580e-03,
+ -1.0998557e-02,
+ -1.1173409e-02,
+ 1.0455756e-02,
+ 2.0686293e-02,
+ -5.2032238e-03,
+ -3.1896964e-02,
+ -7.4998410e-03,
+ 4.3362070e-02,
+ 3.2502845e-02,
+ -5.3328082e-02,
+ -8.5621715e-02,
+ 6.0117975e-02,
+ 3.1128189e-01,
+ 4.3769023e-01,
+ 3.1128189e-01,
+ 6.0117975e-02,
+ -8.5621715e-02,
+ -5.3328082e-02,
+ 3.2502845e-02,
+ 4.3362070e-02,
+ -7.4998410e-03,
+ -3.1896964e-02,
+ -5.2032238e-03,
+ 2.0686293e-02,
+ 1.0455756e-02,
+ -1.1173409e-02,
+ -1.0998557e-02,
+ 4.2178580e-03,
+ 8.9516686e-03,
+ 6.4301129e-18,
+ -5.9935520e-03,
+ -1.8868084e-03,
+ 3.2744040e-03,
+ 2.2031884e-03,
+ -1.3599906e-03,
+ -1.7744775e-03,
+ 2.9683491e-04,
+ 1.2388536e-03,
+ 2.0713841e-04,
+ -9.0525491e-04
+};
+
+const static float t2_exp[53] = {
+ 9.0380036e-04,
+ -2.0680559e-04,
+ -1.2368630e-03,
+ -2.9635796e-04,
+ 1.7716263e-03,
+ 1.3578053e-03,
+ -2.1996482e-03,
+ -3.2691427e-03,
+ 1.8837767e-03,
+ 5.9839217e-03,
+ -6.4197810e-18,
+ -8.9372853e-03,
+ -4.2110807e-03,
+ 1.0980885e-02,
+ 1.1155456e-02,
+ -1.0438956e-02,
+ -2.0653054e-02,
+ 5.1948633e-03,
+ 3.1845711e-02,
+ 7.4877902e-03,
+ -4.3292396e-02,
+ -3.2450620e-02,
+ 5.3242393e-02,
+ 8.5484132e-02,
+ -6.0021374e-02,
+ -3.1078172e-01,
+ 5.6184036e-01,
+ -3.1078172e-01,
+ -6.0021374e-02,
+ 8.5484132e-02,
+ 5.3242393e-02,
+ -3.2450620e-02,
+ -4.3292396e-02,
+ 7.4877902e-03,
+ 3.1845711e-02,
+ 5.1948633e-03,
+ -2.0653054e-02,
+ -1.0438956e-02,
+ 1.1155456e-02,
+ 1.0980885e-02,
+ -4.2110807e-03,
+ -8.9372853e-03,
+ -6.4197810e-18,
+ 5.9839217e-03,
+ 1.8837767e-03,
+ -3.2691427e-03,
+ -2.1996482e-03,
+ 1.3578053e-03,
+ 1.7716263e-03,
+ -2.9635796e-04,
+ -1.2368630e-03,
+ -2.0680559e-04,
+ 9.0380036e-04
+};
+
+const static float t3_exp[107] = {
+ -1.8970841e-06,
+ -7.1057165e-04,
+ 5.4005696e-04,
+ 4.6233178e-04,
+ 2.0572044e-04,
+ 3.5209916e-04,
+ -1.4098573e-03,
+ 1.1279077e-04,
+ -6.2994129e-04,
+ 1.1450432e-03,
+ 1.3637283e-03,
+ -6.4360141e-04,
+ 3.6509900e-04,
+ -3.2864159e-03,
+ 7.0192874e-04,
+ 3.7524730e-04,
+ 2.0256115e-03,
+ 3.0641893e-03,
+ -3.6618244e-03,
+ 7.5592739e-05,
+ -5.5586505e-03,
+ 2.3849572e-03,
+ 4.0114378e-03,
+ 1.6636450e-03,
+ 4.7835698e-03,
+ -1.0191196e-02,
+ -3.8158931e-04,
+ -5.5551580e-03,
+ 5.3901658e-03,
+ 1.1366769e-02,
+ -3.0000482e-03,
+ 4.9341680e-03,
+ -2.0093076e-02,
+ 5.5752542e-17,
+ 1.2093617e-03,
+ 8.6089745e-03,
+ 2.2382140e-02,
+ -1.6854567e-02,
+ 1.6913920e-03,
+ -3.1222520e-02,
+ 3.2711059e-03,
+ 2.2604836e-02,
+ 8.1451107e-03,
+ 3.7583180e-02,
+ -5.2293688e-02,
+ -8.0551542e-03,
+ -4.0092729e-02,
+ 1.5582236e-02,
+ 9.7452506e-02,
+ -1.6183170e-02,
+ 8.3281815e-02,
+ -2.8196752e-01,
+ -1.0965768e-01,
+ 5.2867508e-01,
+ -1.0965768e-01,
+ -2.8196752e-01,
+ 8.3281815e-02,
+ -1.6183170e-02,
+ 9.7452506e-02,
+ 1.5582236e-02,
+ -4.0092729e-02,
+ -8.0551542e-03,
+ -5.2293688e-02,
+ 3.7583180e-02,
+ 8.1451107e-03,
+ 2.2604836e-02,
+ 3.2711059e-03,
+ -3.1222520e-02,
+ 1.6913920e-03,
+ -1.6854567e-02,
+ 2.2382140e-02,
+ 8.6089745e-03,
+ 1.2093617e-03,
+ 5.5752542e-17,
+ -2.0093076e-02,
+ 4.9341680e-03,
+ -3.0000482e-03,
+ 1.1366769e-02,
+ 5.3901658e-03,
+ -5.5551580e-03,
+ -3.8158931e-04,
+ -1.0191196e-02,
+ 4.7835698e-03,
+ 1.6636450e-03,
+ 4.0114378e-03,
+ 2.3849572e-03,
+ -5.5586505e-03,
+ 7.5592739e-05,
+ -3.6618244e-03,
+ 3.0641893e-03,
+ 2.0256115e-03,
+ 3.7524730e-04,
+ 7.0192874e-04,
+ -3.2864159e-03,
+ 3.6509900e-04,
+ -6.4360141e-04,
+ 1.3637283e-03,
+ 1.1450432e-03,
+ -6.2994129e-04,
+ 1.1279077e-04,
+ -1.4098573e-03,
+ 3.5209916e-04,
+ 2.0572044e-04,
+ 4.6233178e-04,
+ 5.4005696e-04,
+ -7.1057165e-04,
+ -1.8970841e-06
+};
+
+
+void
+qa_gr_firdes::t1 ()
+{
+ vector<float> taps =
+ gr_firdes::low_pass ( 1.0,
+ 8000,
+ 1750,
+ 500,
+ gr_firdes::WIN_HAMMING);
+
+ // cout << "ntaps: " << taps.size () << endl;
+ // print_taps (cout, taps);
+
+ CPPUNIT_ASSERT_EQUAL (NELEM (t1_exp), taps.size ());
+ for (unsigned int i = 0; i < taps.size (); i++)
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (t1_exp[i], taps[i], 1e-9);
+
+ check_symmetry (taps);
+}
+
+void
+qa_gr_firdes::t2 ()
+{
+ vector<float> taps =
+ gr_firdes::high_pass ( 1.0,
+ 8000,
+ 1750,
+ 500,
+ gr_firdes::WIN_HAMMING);
+
+ // cout << "ntaps: " << taps.size () << endl;
+ // print_taps (cout, taps);
+
+ CPPUNIT_ASSERT_EQUAL (NELEM (t2_exp), taps.size ());
+
+ for (unsigned int i = 0; i < taps.size (); i++)
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (t2_exp[i], taps[i], 1e-9);
+
+ check_symmetry (taps);
+}
+
+void
+qa_gr_firdes::t3 ()
+{
+ vector<float> taps =
+ gr_firdes::band_pass ( 1.0,
+ 20e6,
+ 5.75e6 - (5.28e6/2),
+ 5.75e6 + (5.28e6/2),
+ 0.62e6,
+ gr_firdes::WIN_HAMMING);
+
+ // cout << "ntaps: " << taps.size () << endl;
+ // print_taps (cout, taps);
+
+ CPPUNIT_ASSERT_EQUAL (NELEM (t3_exp), taps.size ());
+
+ for (unsigned int i = 0; i < taps.size (); i++)
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (t3_exp[i], taps[i], 1e-7);
+
+ check_symmetry (taps);
+}
+
+void
+qa_gr_firdes::t4 ()
+{
+}
diff --git a/gnuradio-core/src/lib/general/qa_gr_firdes.h b/gnuradio-core/src/lib/general/qa_gr_firdes.h
new file mode 100644
index 0000000000..8fb4d5a3dd
--- /dev/null
+++ b/gnuradio-core/src/lib/general/qa_gr_firdes.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _QA_GR_FIRDES_H_
+#define _QA_GR_FIRDES_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_firdes : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gr_firdes);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST (t3);
+ CPPUNIT_TEST (t4);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void t1 ();
+ void t2 ();
+ void t3 ();
+ void t4 ();
+
+};
+
+
+#endif /* _QA_GR_FIRDES_H_ */
diff --git a/gnuradio-core/src/lib/general/qa_gr_fxpt.cc b/gnuradio-core/src/lib/general/qa_gr_fxpt.cc
new file mode 100644
index 0000000000..6cd582ad94
--- /dev/null
+++ b/gnuradio-core/src/lib/general/qa_gr_fxpt.cc
@@ -0,0 +1,94 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <qa_gr_fxpt.h>
+#include <gr_fxpt.h>
+#include <cppunit/TestAssert.h>
+#include <iostream>
+#include <stdio.h>
+#include <unistd.h>
+#include <math.h>
+
+static const float SIN_COS_TOLERANCE = 1e-5;
+
+void
+qa_gr_fxpt::t0 ()
+{
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (M_PI/2, gr_fxpt::fixed_to_float (0x40000000), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (0.0, gr_fxpt::fixed_to_float (0x00000000), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (-M_PI, gr_fxpt::fixed_to_float (0x80000000), SIN_COS_TOLERANCE);
+
+ if (0){
+ /*
+ * These are disabled because of some precision issues.
+ *
+ * Different compilers seem to have different opinions on whether
+ * the calulations are done single or double (or extended)
+ * precision. Any of the answers are fine for our real purpose, but
+ * sometimes the answer is off by a few bits at the bottom.
+ * Hence, the disabled check.
+ */
+ CPPUNIT_ASSERT_EQUAL ((gr_int32) 0x40000000, gr_fxpt::float_to_fixed (M_PI/2));
+ CPPUNIT_ASSERT_EQUAL ((gr_int32) 0, gr_fxpt::float_to_fixed (0));
+ CPPUNIT_ASSERT_EQUAL ((gr_int32) 0x80000000, gr_fxpt::float_to_fixed (-M_PI));
+ }
+}
+
+void
+qa_gr_fxpt::t1 ()
+{
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL ( 0, gr_fxpt::sin (0x00000000), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL ( 0.707106781, gr_fxpt::sin (0x20000000), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL ( 1, gr_fxpt::sin (0x40000000), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL ( 0.707106781, gr_fxpt::sin (0x60000000), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL ( 0, gr_fxpt::sin (0x7fffffff), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL ( 0, gr_fxpt::sin (0x80000000), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL ( 0, gr_fxpt::sin (0x80000001), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (-1, gr_fxpt::sin (-0x40000000), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (-0.707106781, gr_fxpt::sin (-0x20000000), SIN_COS_TOLERANCE);
+
+
+ for (float p = -M_PI; p < M_PI; p += 2 * M_PI / 3600){
+ float expected = sin (p);
+ float actual = gr_fxpt::sin (gr_fxpt::float_to_fixed (p));
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (expected, actual, SIN_COS_TOLERANCE);
+ }
+}
+
+void
+qa_gr_fxpt::t2 ()
+{
+ for (float p = -M_PI; p < M_PI; p += 2 * M_PI / 3600){
+ float expected = cos (p);
+ float actual = gr_fxpt::cos (gr_fxpt::float_to_fixed (p));
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (expected, actual, SIN_COS_TOLERANCE);
+ }
+}
+
+void
+qa_gr_fxpt::t3 ()
+{
+}
diff --git a/gnuradio-core/src/lib/general/qa_gr_fxpt.h b/gnuradio-core/src/lib/general/qa_gr_fxpt.h
new file mode 100644
index 0000000000..a21be5ccd3
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_QA_GR_FXPT_H
+#define INCLUDED_QA_GR_FXPT_H
+
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_fxpt : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gr_fxpt);
+ CPPUNIT_TEST (t0);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST (t3);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void t0 ();
+ void t1 ();
+ void t2 ();
+ void t3 ();
+
+};
+
+#endif /* INCLUDED_QA_GR_FXPT_H */
+
+
diff --git a/gnuradio-core/src/lib/general/qa_gr_fxpt_nco.cc b/gnuradio-core/src/lib/general/qa_gr_fxpt_nco.cc
new file mode 100644
index 0000000000..5b774fb841
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <qa_gr_fxpt_nco.h>
+#include <gr_fxpt_nco.h>
+#include <gr_nco.h>
+#include <cppunit/TestAssert.h>
+#include <iostream>
+#include <stdio.h>
+#include <unistd.h>
+#include <math.h>
+
+static const float SIN_COS_TOLERANCE = 1e-5;
+
+//static const float SIN_COS_FREQ = 5003;
+static const float SIN_COS_FREQ = 4096;
+
+static const int SIN_COS_BLOCK_SIZE = 100000;
+
+static double max_d(double a, double b)
+{
+ return fabs(a) > fabs(b) ? a : b;
+}
+
+void
+qa_gr_fxpt_nco::t0 ()
+{
+ gr_nco<float,float> ref_nco;
+ gr_fxpt_nco new_nco;
+ double max_error = 0, max_phase_error = 0;
+
+ ref_nco.set_freq ((float)(2 * M_PI / SIN_COS_FREQ));
+ new_nco.set_freq ((float)(2 * M_PI / SIN_COS_FREQ));
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_nco.get_freq(), new_nco.get_freq(), SIN_COS_TOLERANCE);
+
+ for (int i = 0; i < SIN_COS_BLOCK_SIZE; i++){
+ float ref_sin = ref_nco.sin ();
+ float new_sin = new_nco.sin ();
+ //printf ("i = %6d\n", i);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_sin, new_sin, SIN_COS_TOLERANCE);
+
+ max_error = max_d (max_error, ref_sin-new_sin);
+
+ float ref_cos = ref_nco.cos ();
+ float new_cos = new_nco.cos ();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_cos, new_cos, SIN_COS_TOLERANCE);
+
+ max_error = max_d (max_error, ref_cos-new_cos);
+
+ ref_nco.step ();
+ new_nco.step ();
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_nco.get_phase(), new_nco.get_phase(), SIN_COS_TOLERANCE);
+
+ max_phase_error = max_d (max_phase_error, ref_nco.get_phase()-new_nco.get_phase());
+ }
+ // printf ("Fxpt max error %.9f, max phase error %.9f\n", max_error, max_phase_error);
+}
+
+void
+qa_gr_fxpt_nco::t1 ()
+{
+ gr_nco<float,float> ref_nco;
+ gr_fxpt_nco new_nco;
+ gr_complex ref_block[SIN_COS_BLOCK_SIZE];
+ gr_complex new_block[SIN_COS_BLOCK_SIZE];
+ double max_error = 0;
+
+ ref_nco.set_freq ((float)(2 * M_PI / SIN_COS_FREQ));
+ new_nco.set_freq ((float)(2 * M_PI / SIN_COS_FREQ));
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_nco.get_freq(), new_nco.get_freq(), SIN_COS_TOLERANCE);
+
+ ref_nco.sincos ((gr_complex*)ref_block, SIN_COS_BLOCK_SIZE);
+ new_nco.sincos ((gr_complex*)new_block, SIN_COS_BLOCK_SIZE);
+
+ for (int i = 0; i < SIN_COS_BLOCK_SIZE; i++){
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_block[i].real(), new_block[i].real(), SIN_COS_TOLERANCE);
+ max_error = max_d (max_error, ref_block[i].real()-new_block[i].real());
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_block[i].imag(), new_block[i].imag(), SIN_COS_TOLERANCE);
+ max_error = max_d (max_error, ref_block[i].imag()-new_block[i].imag());
+ }
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_nco.get_phase(), new_nco.get_phase(), SIN_COS_TOLERANCE);
+ // printf ("Fxpt max error %.9f, max phase error %.9f\n", max_error, max_phase_error);
+}
+
+void
+qa_gr_fxpt_nco::t2 ()
+{
+}
+
+void
+qa_gr_fxpt_nco::t3 ()
+{
+}
diff --git a/gnuradio-core/src/lib/general/qa_gr_fxpt_nco.h b/gnuradio-core/src/lib/general/qa_gr_fxpt_nco.h
new file mode 100644
index 0000000000..3d0c84a01d
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_QA_GR_FXPT_NCO_H
+#define INCLUDED_QA_GR_FXPT_NCO_H
+
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_fxpt_nco : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gr_fxpt_nco);
+ CPPUNIT_TEST (t0);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST (t3);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void t0 ();
+ void t1 ();
+ void t2 ();
+ void t3 ();
+
+};
+
+#endif /* INCLUDED_QA_GR_FXPT_NCO_H */
+
+
diff --git a/gnuradio-core/src/lib/general/qa_gr_fxpt_vco.cc b/gnuradio-core/src/lib/general/qa_gr_fxpt_vco.cc
new file mode 100644
index 0000000000..70c2da366a
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <qa_gr_fxpt_vco.h>
+#include <gr_fxpt_vco.h>
+#include <gr_vco.h>
+#include <cppunit/TestAssert.h>
+#include <iostream>
+#include <stdio.h>
+#include <unistd.h>
+#include <math.h>
+
+static const float SIN_COS_TOLERANCE = 1e-5;
+
+static const float SIN_COS_K = 0.42;
+static const float SIN_COS_AMPL = 0.8;
+
+static const int SIN_COS_BLOCK_SIZE = 100000;
+
+static double max_d(double a, double b)
+{
+ return fabs(a) > fabs(b) ? a : b;
+}
+
+void
+qa_gr_fxpt_vco::t0 ()
+{
+ gr_vco<float,float> ref_vco;
+ gr_fxpt_vco new_vco;
+ double max_error = 0, max_phase_error = 0;
+ float input[SIN_COS_BLOCK_SIZE];
+
+ for (int i = 0; i < SIN_COS_BLOCK_SIZE; i++){
+ input[i] = sin(i);
+ }
+
+ for (int i = 0; i < SIN_COS_BLOCK_SIZE; i++){
+ float ref_cos = ref_vco.cos ();
+ float new_cos = new_vco.cos ();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_cos, new_cos, SIN_COS_TOLERANCE);
+
+ max_error = max_d (max_error, ref_cos-new_cos);
+
+ ref_vco.adjust_phase (input[i]);
+ new_vco.adjust_phase (input[i]);
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_vco.get_phase(), new_vco.get_phase(), SIN_COS_TOLERANCE);
+
+ max_phase_error = max_d (max_phase_error, ref_vco.get_phase()-new_vco.get_phase());
+ }
+ // printf ("Fxpt max error %.9f, max phase error %.9f\n", max_error, max_phase_error);
+}
+
+
+void
+qa_gr_fxpt_vco::t1 ()
+{
+ gr_vco<float,float> ref_vco;
+ gr_fxpt_vco new_vco;
+ float ref_block[SIN_COS_BLOCK_SIZE];
+ float new_block[SIN_COS_BLOCK_SIZE];
+ float input[SIN_COS_BLOCK_SIZE];
+ double max_error = 0;
+
+ for (int i = 0; i < SIN_COS_BLOCK_SIZE; i++){
+ input[i] = sin(i);
+ }
+
+ ref_vco.cos (ref_block, input, SIN_COS_BLOCK_SIZE, SIN_COS_K, SIN_COS_AMPL);
+ new_vco.cos (new_block, input, SIN_COS_BLOCK_SIZE, SIN_COS_K, SIN_COS_AMPL);
+
+ for (int i = 0; i < SIN_COS_BLOCK_SIZE; i++){
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_block[i], new_block[i], SIN_COS_TOLERANCE);
+ max_error = max_d (max_error, ref_block[i]-new_block[i]);
+ }
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_vco.get_phase(), new_vco.get_phase(), SIN_COS_TOLERANCE);
+ // printf ("Fxpt max error %.9f, max phase error %.9f\n", max_error, ref_vco.get_phase()-new_vco.get_phase());
+}
+
+void
+qa_gr_fxpt_vco::t2 ()
+{
+}
+
+void
+qa_gr_fxpt_vco::t3 ()
+{
+}
diff --git a/gnuradio-core/src/lib/general/qa_gr_fxpt_vco.h b/gnuradio-core/src/lib/general/qa_gr_fxpt_vco.h
new file mode 100644
index 0000000000..80ea0253c2
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_QA_GR_FXPT_VCO_H
+#define INCLUDED_QA_GR_FXPT_VCO_H
+
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_fxpt_vco : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gr_fxpt_vco);
+ CPPUNIT_TEST (t0);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST (t3);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void t0 ();
+ void t1 ();
+ void t2 ();
+ void t3 ();
+
+};
+
+#endif /* INCLUDED_QA_GR_FXPT_VCO_H */
+
+
diff --git a/gnuradio-core/src/lib/general/random.h b/gnuradio-core/src/lib/general/random.h
new file mode 100644
index 0000000000..816aca3492
--- /dev/null
+++ b/gnuradio-core/src/lib/general/random.h
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _RANDOM_H_
+#define _RANDOM_H_
+
+// we use this because some systems (solaris) define RAND_MAX as 32767
+
+static const int RANDOM_MAX = 2147483647;
+
+#include <stdlib.h>
+
+#endif // _RANDOM_H_
diff --git a/gnuradio-core/src/lib/general/sine_table.h b/gnuradio-core/src/lib/general/sine_table.h
new file mode 100644
index 0000000000..69834943bc
--- /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/io/Makefile.am b/gnuradio-core/src/lib/io/Makefile.am
new file mode 100644
index 0000000000..e390e1344a
--- /dev/null
+++ b/gnuradio-core/src/lib/io/Makefile.am
@@ -0,0 +1,96 @@
+#
+# Copyright 2001,2003,2004 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+include $(top_srcdir)/Makefile.common
+
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES)
+
+noinst_LTLIBRARIES = libio.la
+
+
+libio_la_SOURCES = \
+ gr_file_sink.cc \
+ gr_file_source.cc \
+ gr_file_descriptor_sink.cc \
+ gr_file_descriptor_source.cc \
+ gr_message_sink.cc \
+ gr_message_source.cc \
+ gr_oscope_guts.cc \
+ gr_oscope_sink_f.cc \
+ gr_oscope_sink_x.cc \
+ gri_logger.cc \
+ i2c.cc \
+ i2c_bitbang.cc \
+ i2c_bbio.cc \
+ i2c_bbio_pp.cc \
+ microtune_4702.cc \
+ microtune_4937.cc \
+ microtune_4702_eval_board.cc \
+ microtune_4937_eval_board.cc \
+ microtune_xxxx.cc \
+ microtune_xxxx_eval_board.cc \
+ ppio.cc \
+ ppio_ppdev.cc \
+ sdr_1000.cc
+
+grinclude_HEADERS = \
+ gr_file_sink.h \
+ gr_file_source.h \
+ gr_file_descriptor_sink.h \
+ gr_file_descriptor_source.h \
+ gr_message_sink.h \
+ gr_message_source.h \
+ gr_oscope_guts.h \
+ gr_oscope_sink_f.h \
+ gr_oscope_sink_x.h \
+ gr_trigger_mode.h \
+ gri_logger.h \
+ i2c.h \
+ i2c_bitbang.h \
+ i2c_bbio.h \
+ i2c_bbio_pp.h \
+ microtune_4702.h \
+ microtune_4937.h \
+ microtune_4702_eval_board.h \
+ microtune_4937_eval_board.h \
+ microtune_eval_board_defs.h \
+ microtune_xxxx.h \
+ microtune_xxxx_eval_board.h \
+ ppio.h \
+ ppio_ppdev.h \
+ sdr_1000.h
+
+
+swiginclude_HEADERS = \
+ io.i \
+ gr_file_sink.i \
+ gr_file_source.i \
+ gr_file_descriptor_sink.i \
+ gr_file_descriptor_source.i \
+ gr_message_sink.i \
+ gr_message_source.i \
+ gr_oscope_sink.i \
+ microtune_xxxx_eval_board.i \
+ microtune_4702_eval_board.i \
+ microtune_4937_eval_board.i \
+ ppio.i \
+ sdr_1000.i
diff --git a/gnuradio-core/src/lib/io/gr_file_descriptor_sink.cc b/gnuradio-core/src/lib/io/gr_file_descriptor_sink.cc
new file mode 100644
index 0000000000..6a0b1ca4ab
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_descriptor_sink.cc
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_file_descriptor_sink.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+
+
+gr_file_descriptor_sink::gr_file_descriptor_sink (size_t itemsize, int fd)
+ : gr_sync_block ("file_descriptor_sink",
+ gr_make_io_signature (1, 1, itemsize),
+ gr_make_io_signature (0, 0, 0)),
+ d_itemsize (itemsize), d_fd (fd)
+{
+}
+
+gr_file_descriptor_sink_sptr
+gr_make_file_descriptor_sink (size_t itemsize, int fd)
+{
+ return gr_file_descriptor_sink_sptr (new gr_file_descriptor_sink (itemsize, fd));
+}
+
+gr_file_descriptor_sink::~gr_file_descriptor_sink ()
+{
+ close (d_fd);
+}
+
+int
+gr_file_descriptor_sink::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ char *inbuf = (char *) input_items[0];
+ unsigned long byte_size = noutput_items * d_itemsize;
+
+ while (byte_size > 0){
+ ssize_t r;
+
+ r = write (d_fd, inbuf, byte_size);
+ if (r == -1){
+ if (errno == EINTR)
+ continue;
+ else {
+ perror ("gr_file_descriptor_sink");
+ return -1; // indicate we're done
+ }
+ }
+ else {
+ byte_size -= r;
+ inbuf += r;
+ }
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/io/gr_file_descriptor_sink.h b/gnuradio-core/src/lib/io/gr_file_descriptor_sink.h
new file mode 100644
index 0000000000..a811ce7056
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_descriptor_sink.h
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_FILE_DESCRIPTOR_SINK_H
+#define INCLUDED_GR_FILE_DESCRIPTOR_SINK_H
+
+#include <gr_sync_block.h>
+
+class gr_file_descriptor_sink;
+typedef boost::shared_ptr<gr_file_descriptor_sink> gr_file_descriptor_sink_sptr;
+
+gr_file_descriptor_sink_sptr gr_make_file_descriptor_sink (size_t itemsize, int fd);
+
+/*!
+ * \brief Write stream to file descriptor.
+ * \ingroup sink
+ */
+
+class gr_file_descriptor_sink : public gr_sync_block
+{
+ friend gr_file_descriptor_sink_sptr gr_make_file_descriptor_sink (size_t itemsize, int fd);
+
+ private:
+ size_t d_itemsize;
+ int d_fd;
+
+ protected:
+ gr_file_descriptor_sink (size_t itemsize, int fd);
+
+ public:
+ ~gr_file_descriptor_sink ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_FILE_DESCRIPTOR_SINK_H */
diff --git a/gnuradio-core/src/lib/io/gr_file_descriptor_sink.i b/gnuradio-core/src/lib/io/gr_file_descriptor_sink.i
new file mode 100644
index 0000000000..e058186569
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,file_descriptor_sink)
+
+gr_file_descriptor_sink_sptr
+gr_make_file_descriptor_sink (size_t itemsize, int fd);
+
+class gr_file_descriptor_sink : public gr_sync_block
+{
+ protected:
+ gr_file_descriptor_sink (size_t itemsize, int fd);
+
+ public:
+ ~gr_file_descriptor_sink ();
+};
diff --git a/gnuradio-core/src/lib/io/gr_file_descriptor_source.cc b/gnuradio-core/src/lib/io/gr_file_descriptor_source.cc
new file mode 100644
index 0000000000..38b9da010e
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_descriptor_source.cc
@@ -0,0 +1,146 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_file_descriptor_source.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+
+
+gr_file_descriptor_source::gr_file_descriptor_source (size_t itemsize,
+ int fd,
+ bool repeat)
+ : gr_sync_block ("file_descriptor_source",
+ gr_make_io_signature (0, 0, 0),
+ gr_make_io_signature (1, 1, itemsize)),
+ d_itemsize (itemsize), d_fd (fd), d_repeat (repeat),
+ d_residue (new unsigned char[itemsize]), d_residue_len (0)
+{
+}
+
+// public constructor that returns a shared_ptr
+
+gr_file_descriptor_source_sptr
+gr_make_file_descriptor_source (size_t itemsize, int fd, bool repeat)
+{
+ return gr_file_descriptor_source_sptr (
+ new gr_file_descriptor_source (itemsize, fd, repeat));
+}
+
+gr_file_descriptor_source::~gr_file_descriptor_source ()
+{
+ close (d_fd);
+ delete [] d_residue;
+}
+
+int
+gr_file_descriptor_source::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ assert (noutput_items > 0);
+
+ char *o = (char *) output_items[0];
+ int nread = 0;
+
+ while (1){
+ int r = read_items (o, noutput_items - nread);
+ if (r == -1){
+ if (errno == EINTR)
+ continue;
+ else {
+ perror ("file_descriptor_source[read]");
+ return -1;
+ }
+ }
+ else if (r == 0){ // end of file
+ if (!d_repeat)
+ break;
+ else {
+ flush_residue ();
+ if (lseek (d_fd, 0, SEEK_SET) == -1){
+ perror ("file_descriptor_source[lseek]");
+ return -1;
+ }
+ }
+ }
+ else {
+ o += r * d_itemsize;
+ nread += r;
+ break;
+ }
+ }
+
+ if (nread == 0) // EOF
+ return -1;
+
+ return nread;
+}
+
+int
+gr_file_descriptor_source::read_items (char *buf, int nitems)
+{
+ assert (nitems > 0);
+ assert (d_residue_len < d_itemsize);
+
+ int nbytes_read = 0;
+
+ if (d_residue_len > 0){
+ memcpy (buf, d_residue, d_residue_len);
+ nbytes_read = d_residue_len;
+ d_residue_len = 0;
+ }
+
+ int r = read (d_fd, buf + nbytes_read, nitems * d_itemsize - nbytes_read);
+ if (r <= 0){
+ handle_residue (buf, nbytes_read);
+ return r;
+ }
+
+ r = handle_residue (buf, r + nbytes_read);
+
+ if (r == 0) // block until we get something
+ return read_items (buf, nitems);
+
+ return r;
+}
+
+int
+gr_file_descriptor_source::handle_residue (char *buf, int nbytes_read)
+{
+ assert (nbytes_read >= 0);
+ int nitems_read = nbytes_read / d_itemsize;
+ d_residue_len = nbytes_read % d_itemsize;
+ if (d_residue_len > 0){
+ // fprintf (stderr, "handle_residue: %d\n", d_residue_len);
+ memcpy (d_residue, buf + nbytes_read - d_residue_len, d_residue_len);
+ }
+ return nitems_read;
+}
diff --git a/gnuradio-core/src/lib/io/gr_file_descriptor_source.h b/gnuradio-core/src/lib/io/gr_file_descriptor_source.h
new file mode 100644
index 0000000000..9f678dcf57
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_descriptor_source.h
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_FILE_DESCRIPTOR_SOURCE_H
+#define INCLUDED_GR_FILE_DESCRIPTOR_SOURCE_H
+
+#include <gr_sync_block.h>
+
+class gr_file_descriptor_source;
+typedef boost::shared_ptr<gr_file_descriptor_source> gr_file_descriptor_source_sptr;
+
+gr_file_descriptor_source_sptr
+gr_make_file_descriptor_source (size_t itemsize, int fd, bool repeat = false);
+
+/*!
+ * \brief Read stream from file descriptor.
+ * \ingroup source
+ */
+
+class gr_file_descriptor_source : public gr_sync_block
+{
+ friend gr_file_descriptor_source_sptr
+ gr_make_file_descriptor_source (size_t itemsize, int fd, bool repeat);
+ private:
+ size_t d_itemsize;
+ int d_fd;
+ bool d_repeat;
+
+ unsigned char *d_residue;
+ unsigned long d_residue_len;
+
+ protected:
+ gr_file_descriptor_source (size_t itemsize, int fd, bool repeat);
+
+ int read_items (char *buf, int nitems);
+ int handle_residue (char *buf, int nbytes_read);
+ void flush_residue () { d_residue_len = 0; }
+
+
+ public:
+ ~gr_file_descriptor_source ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_FILE_DESCRIPTOR_SOURCE_H */
diff --git a/gnuradio-core/src/lib/io/gr_file_descriptor_source.i b/gnuradio-core/src/lib/io/gr_file_descriptor_source.i
new file mode 100644
index 0000000000..ba9b3894f9
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,file_descriptor_source)
+
+gr_file_descriptor_source_sptr
+gr_make_file_descriptor_source (size_t itemsize, int fd, bool repeat=false);
+
+class gr_file_descriptor_source : public gr_sync_block
+{
+ protected:
+ gr_file_descriptor_source (size_t itemsize, int fd, bool repeat);
+
+ public:
+ ~gr_file_descriptor_source ();
+};
diff --git a/gnuradio-core/src/lib/io/gr_file_sink.cc b/gnuradio-core/src/lib/io/gr_file_sink.cc
new file mode 100644
index 0000000000..d22488bf69
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_sink.cc
@@ -0,0 +1,144 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_file_sink.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+
+// win32 (mingw/msvc) specific
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+#ifdef O_BINARY
+#define OUR_O_BINARY O_BINARY
+#else
+#define OUR_O_BINARY 0
+#endif
+
+// should be handled via configure
+#ifdef O_LARGEFILE
+#define OUR_O_LARGEFILE O_LARGEFILE
+#else
+#define OUR_O_LARGEFILE 0
+#endif
+
+gr_file_sink::gr_file_sink(size_t itemsize, const char *filename)
+ : gr_sync_block ("file_sink",
+ gr_make_io_signature(1, 1, itemsize),
+ gr_make_io_signature(0, 0, 0)),
+ d_itemsize(itemsize), d_fp(0), d_new_fp(0), d_updated(false)
+{
+ if (!open(filename))
+ throw std::runtime_error ("can't open file");
+}
+
+gr_file_sink_sptr
+gr_make_file_sink (size_t itemsize, const char *filename)
+{
+ return gr_file_sink_sptr (new gr_file_sink (itemsize, filename));
+}
+
+gr_file_sink::~gr_file_sink ()
+{
+ close();
+ if (d_fp){
+ fclose((FILE *) d_fp);
+ d_fp = 0;
+ }
+}
+
+bool
+gr_file_sink::open(const char *filename)
+{
+ omni_mutex_lock l(d_mutex); // hold mutex for duration of this function
+
+ // we use the open system call to get access to the O_LARGEFILE flag.
+ int fd;
+ if ((fd = ::open (filename,
+ O_WRONLY|O_CREAT|O_TRUNC|OUR_O_LARGEFILE|OUR_O_BINARY, 0664)) < 0){
+ perror (filename);
+ return false;
+ }
+
+ if (d_new_fp){ // if we've already got a new one open, close it
+ fclose((FILE *) d_new_fp);
+ d_new_fp = 0;
+ }
+
+ if ((d_new_fp = fdopen (fd, "wb")) == NULL){
+ perror (filename);
+ ::close(fd); // don't leak file descriptor if fdopen fails.
+ }
+
+ d_updated = true;
+ return d_new_fp != 0;
+}
+
+void
+gr_file_sink::close()
+{
+ omni_mutex_lock l(d_mutex); // hold mutex for duration of this function
+
+ if (d_new_fp){
+ fclose((FILE *) d_new_fp);
+ d_new_fp = 0;
+ }
+ d_updated = true;
+}
+
+int
+gr_file_sink::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ char *inbuf = (char *) input_items[0];
+ int nwritten = 0;
+
+ if (d_updated){
+ omni_mutex_lock l(d_mutex); // hold mutex for duration of this block
+ if (d_fp)
+ fclose((FILE *)d_fp);
+ d_fp = d_new_fp; // install new file pointer
+ d_new_fp = 0;
+ d_updated = false;
+ }
+
+ if (!d_fp)
+ return noutput_items; // drop output on the floor
+
+ while (nwritten < noutput_items){
+ int count = fwrite (inbuf, d_itemsize, noutput_items - nwritten, (FILE *) d_fp);
+ if (count == 0) // FIXME add error handling
+ break;
+ nwritten += count;
+ inbuf += count * d_itemsize;
+ }
+ return nwritten;
+}
diff --git a/gnuradio-core/src/lib/io/gr_file_sink.h b/gnuradio-core/src/lib/io/gr_file_sink.h
new file mode 100644
index 0000000000..9c11bf72bd
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_sink.h
@@ -0,0 +1,75 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_FILE_SINK_H
+#define INCLUDED_GR_FILE_SINK_H
+
+#include <gr_sync_block.h>
+#include <omnithread.h>
+
+class gr_file_sink;
+typedef boost::shared_ptr<gr_file_sink> gr_file_sink_sptr;
+
+gr_file_sink_sptr gr_make_file_sink(size_t itemsize, const char *filename);
+
+/*!
+ * \brief Write stream to file.
+ * \ingroup sink
+ */
+
+class gr_file_sink : public gr_sync_block
+{
+ friend gr_file_sink_sptr gr_make_file_sink(size_t itemsize, const char *filename);
+
+ private:
+ size_t d_itemsize;
+ void *d_fp; // current FILE pointer
+ void *d_new_fp; // new FILE pointer
+ bool d_updated; // is there a new FILE pointer?
+ omni_mutex d_mutex;
+
+ protected:
+ gr_file_sink(size_t itemsize, const char *filename);
+
+ public:
+ ~gr_file_sink();
+
+ /*!
+ * \brief Open filename and begin output to it.
+ */
+ bool open(const char *filename);
+
+ /*!
+ * \brief Close current output file.
+ *
+ * Closes current output file and ignores any output until
+ * open is called to connect to another file.
+ */
+ void close();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_FILE_SINK_H */
diff --git a/gnuradio-core/src/lib/io/gr_file_sink.i b/gnuradio-core/src/lib/io/gr_file_sink.i
new file mode 100644
index 0000000000..ffcf02aa6f
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,file_sink)
+
+gr_file_sink_sptr
+gr_make_file_sink (size_t itemsize, const char *filename);
+
+class gr_file_sink : public gr_sync_block
+{
+ protected:
+ gr_file_sink (size_t itemsize, const char *filename);
+
+ public:
+ ~gr_file_sink ();
+
+ /*!
+ * \brief open filename and begin output to it.
+ */
+ bool open(const char *filename);
+
+ /*!
+ * \brief close current output file.
+ */
+ void close();
+};
diff --git a/gnuradio-core/src/lib/io/gr_file_source.cc b/gnuradio-core/src/lib/io/gr_file_source.cc
new file mode 100644
index 0000000000..2573a37e0d
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_source.cc
@@ -0,0 +1,131 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_file_source.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+
+// win32 (mingw/msvc) specific
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+#ifdef O_BINARY
+#define OUR_O_BINARY O_BINARY
+#else
+#define OUR_O_BINARY 0
+#endif
+// should be handled via configure
+#ifdef O_LARGEFILE
+#define OUR_O_LARGEFILE O_LARGEFILE
+#else
+#define OUR_O_LARGEFILE 0
+#endif
+
+gr_file_source::gr_file_source (size_t itemsize, const char *filename, bool repeat)
+ : gr_sync_block ("file_source",
+ gr_make_io_signature (0, 0, 0),
+ gr_make_io_signature (1, 1, itemsize)),
+ d_itemsize (itemsize), d_fp (0), d_repeat (repeat)
+{
+ // we use "open" to use to the O_LARGEFILE flag
+
+ int fd;
+ if ((fd = open (filename, O_RDONLY | OUR_O_LARGEFILE | OUR_O_BINARY)) < 0){
+ perror (filename);
+ throw std::runtime_error ("can't open file");
+ }
+
+ if ((d_fp = fdopen (fd, "rb")) == NULL){
+ perror (filename);
+ throw std::runtime_error ("can't open file");
+ }
+}
+
+// public constructor that returns a shared_ptr
+
+gr_file_source_sptr
+gr_make_file_source (size_t itemsize, const char *filename, bool repeat)
+{
+ return gr_file_source_sptr (new gr_file_source (itemsize, filename, repeat));
+}
+
+gr_file_source::~gr_file_source ()
+{
+ fclose ((FILE *) d_fp);
+}
+
+int
+gr_file_source::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ char *o = (char *) output_items[0];
+ int i;
+ int size = noutput_items;
+
+ while (size) {
+ i = fread(o, d_itemsize, size, (FILE *) d_fp);
+
+ size -= i;
+ o += i * d_itemsize;
+
+ if (size == 0) // done
+ break;
+
+ if (i > 0) // short read, try again
+ continue;
+
+ // We got a zero from fread. This is either EOF or error. In
+ // any event, if we're in repeat mode, seek back to the beginning
+ // of the file and try again, else break
+
+ if (!d_repeat)
+ break;
+
+ if (fseek ((FILE *) d_fp, 0, SEEK_SET) == -1) {
+ fprintf(stderr, "[%s] fseek failed\n", __FILE__);
+ exit(-1);
+ }
+ }
+
+ if (size > 0){ // EOF or error
+ if (size == noutput_items) // we didn't read anything; say we're done
+ return -1;
+ return noutput_items - size; // else return partial result
+ }
+
+ return noutput_items;
+}
+
+bool
+gr_file_source::seek (long seek_point, int whence)
+{
+ return fseek ((FILE *) d_fp, seek_point * d_itemsize, whence) == 0;
+}
diff --git a/gnuradio-core/src/lib/io/gr_file_source.h b/gnuradio-core/src/lib/io/gr_file_source.h
new file mode 100644
index 0000000000..6b635c53bc
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_FILE_SOURCE_H
+#define INCLUDED_GR_FILE_SOURCE_H
+
+#include <gr_sync_block.h>
+
+class gr_file_source;
+typedef boost::shared_ptr<gr_file_source> gr_file_source_sptr;
+
+gr_file_source_sptr
+gr_make_file_source (size_t itemsize, const char *filename, bool repeat = false);
+
+/*!
+ * \brief Read stream from file
+ * \ingroup source
+ */
+
+class gr_file_source : public gr_sync_block
+{
+ friend gr_file_source_sptr gr_make_file_source (size_t itemsize,
+ const char *filename,
+ bool repeat);
+ private:
+ size_t d_itemsize;
+ void *d_fp;
+ bool d_repeat;
+
+ protected:
+ gr_file_source (size_t itemsize, const char *filename, bool repeat);
+
+ public:
+ ~gr_file_source ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ /*!
+ * \brief seek file to \p seek_point relative to \p whence
+ *
+ * \param seek_point sample offset in file
+ * \param whence one of SEEK_SET, SEEK_CUR, SEEK_END (man fseek)
+ */
+ bool seek (long seek_point, int whence);
+};
+
+#endif /* INCLUDED_GR_FILE_SOURCE_H */
diff --git a/gnuradio-core/src/lib/io/gr_file_source.i b/gnuradio-core/src/lib/io/gr_file_source.i
new file mode 100644
index 0000000000..08fdfaf930
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_source.i
@@ -0,0 +1,43 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+%constant int SEEK_SET = 0; /* Seek from beginning of file. */
+%constant int SEEK_CUR = 1; /* Seek from current position. */
+%constant int SEEK_END = 2; /* Seek from end of file. */
+
+
+GR_SWIG_BLOCK_MAGIC(gr,file_source)
+
+gr_file_source_sptr
+gr_make_file_source (size_t itemsize, const char *filename, bool repeat=false);
+
+class gr_file_source : public gr_sync_block
+{
+ protected:
+ gr_file_source (size_t itemsize, const char *filename, bool repeat);
+
+ public:
+ ~gr_file_source ();
+
+ bool seek (long seek_point, int whence);
+};
diff --git a/gnuradio-core/src/lib/io/gr_message_sink.cc b/gnuradio-core/src/lib/io/gr_message_sink.cc
new file mode 100644
index 0000000000..8a0784ec43
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_sink.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_message_sink.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+
+
+// public constructor that returns a shared_ptr
+
+gr_message_sink_sptr
+gr_make_message_sink (size_t itemsize, gr_msg_queue_sptr msgq, bool dont_block)
+{
+ return gr_message_sink_sptr(new gr_message_sink(itemsize, msgq, dont_block));
+}
+
+gr_message_sink::gr_message_sink (size_t itemsize, gr_msg_queue_sptr msgq, bool dont_block)
+ : gr_sync_block("message_sink",
+ gr_make_io_signature(1, 1, itemsize),
+ gr_make_io_signature(0, 0, 0)),
+ d_itemsize(itemsize), d_msgq(msgq), d_dont_block(dont_block)
+{
+}
+
+gr_message_sink::~gr_message_sink()
+{
+}
+
+int
+gr_message_sink::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const char *in = (const char *) input_items[0];
+
+ // if we'd block, drop the data on the floor and say everything is OK
+ if (d_dont_block && d_msgq->full_p())
+ return noutput_items;
+
+ // build a message to hold whatever we've got
+ gr_message_sptr msg = gr_make_message(0, // msg type
+ d_itemsize, // arg1 for other end
+ noutput_items, // arg2 for other end (redundant)
+ noutput_items * d_itemsize); // len of msg
+ memcpy(msg->msg(), in, noutput_items * d_itemsize);
+
+ d_msgq->handle(msg); // send it
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/io/gr_message_sink.h b/gnuradio-core/src/lib/io/gr_message_sink.h
new file mode 100644
index 0000000000..8011ab290d
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_sink.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_MESSAGE_SINK_H
+#define INCLUDED_GR_MESSAGE_SINK_H
+
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+
+class gr_message_sink;
+typedef boost::shared_ptr<gr_message_sink> gr_message_sink_sptr;
+
+gr_message_sink_sptr gr_make_message_sink (size_t itemsize,
+ gr_msg_queue_sptr msgq,
+ bool dont_block);
+
+/*!
+ * \brief Gather received items into messages and insert into msgq
+ * \ingroup sink
+ */
+class gr_message_sink : public gr_sync_block
+{
+ private:
+ size_t d_itemsize;
+ gr_msg_queue_sptr d_msgq;
+ bool d_dont_block;
+
+ friend gr_message_sink_sptr
+ gr_make_message_sink(size_t itemsize, gr_msg_queue_sptr msgq, bool dont_block);
+
+ protected:
+ gr_message_sink (size_t itemsize, gr_msg_queue_sptr msgq, bool dont_block);
+
+ public:
+ ~gr_message_sink ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_MESSAGE_SINK_H */
diff --git a/gnuradio-core/src/lib/io/gr_message_sink.i b/gnuradio-core/src/lib/io/gr_message_sink.i
new file mode 100644
index 0000000000..ca73479c53
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,message_sink);
+
+gr_message_sink_sptr gr_make_message_sink (size_t itemsize,
+ gr_msg_queue_sptr msgq,
+ bool dont_block);
+
+class gr_message_sink : public gr_sync_block
+{
+ protected:
+ gr_message_sink (size_t itemsize, gr_msg_queue_sptr msgq, bool dont_block);
+
+ public:
+ ~gr_message_sink ();
+};
diff --git a/gnuradio-core/src/lib/io/gr_message_source.cc b/gnuradio-core/src/lib/io/gr_message_source.cc
new file mode 100644
index 0000000000..797433be55
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_source.cc
@@ -0,0 +1,104 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_message_source.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+
+
+// public constructor that returns a shared_ptr
+
+gr_message_source_sptr
+gr_make_message_source(size_t itemsize, int msgq_limit)
+{
+ return gr_message_source_sptr(new gr_message_source(itemsize, msgq_limit));
+}
+
+gr_message_source::gr_message_source (size_t itemsize, int msgq_limit)
+ : gr_sync_block("message_source",
+ gr_make_io_signature(0, 0, 0),
+ gr_make_io_signature(1, 1, itemsize)),
+ d_itemsize(itemsize), d_msgq(gr_make_msg_queue(msgq_limit)), d_msg_offset(0), d_eof(false)
+{
+}
+
+gr_message_source::~gr_message_source()
+{
+}
+
+int
+gr_message_source::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ char *out = (char *) output_items[0];
+ int nn = 0;
+
+ while (nn < noutput_items){
+ if (d_msg){
+ //
+ // Consume whatever we can from the current message
+ //
+ int mm = std::min(noutput_items - nn, (int)((d_msg->length() - d_msg_offset) / d_itemsize));
+ memcpy (out, &(d_msg->msg()[d_msg_offset]), mm * d_itemsize);
+
+ nn += mm;
+ out += mm * d_itemsize;
+ d_msg_offset += mm * d_itemsize;
+ assert(d_msg_offset <= d_msg->length());
+
+ if (d_msg_offset == d_msg->length()){
+ if (d_msg->type() == 1) // type == 1 sets EOF
+ d_eof = true;
+ d_msg.reset();
+ }
+ }
+ else {
+ //
+ // No current message
+ //
+ if (d_msgq->empty_p() && nn > 0){ // no more messages in the queue, return what we've got
+ break;
+ }
+
+ if (d_eof)
+ return -1;
+
+ d_msg = d_msgq->delete_head(); // block, waiting for a message
+ d_msg_offset = 0;
+
+ if ((d_msg->length() % d_itemsize) != 0)
+ throw std::runtime_error("msg length is not a multiple of d_itemsize");
+ }
+ }
+
+ return nn;
+}
diff --git a/gnuradio-core/src/lib/io/gr_message_source.h b/gnuradio-core/src/lib/io/gr_message_source.h
new file mode 100644
index 0000000000..0206012401
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_source.h
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_MESSAGE_SOURCE_H
+#define INCLUDED_GR_MESSAGE_SOURCE_H
+
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+
+class gr_message_source;
+typedef boost::shared_ptr<gr_message_source> gr_message_source_sptr;
+
+gr_message_source_sptr gr_make_message_source (size_t itemsize, int msgq_limit=0);
+
+/*!
+ * \brief Turn received messages into a stream
+ * \ingroup source
+ */
+class gr_message_source : public gr_sync_block
+{
+ private:
+ size_t d_itemsize;
+ gr_msg_queue_sptr d_msgq;
+ gr_message_sptr d_msg;
+ unsigned d_msg_offset;
+ bool d_eof;
+
+ friend gr_message_source_sptr
+ gr_make_message_source(size_t itemsize, int msgq_limit);
+
+ protected:
+ gr_message_source (size_t itemsize, int msgq_limit);
+
+ public:
+ ~gr_message_source ();
+
+ gr_msg_queue_sptr msgq() const { return d_msgq; }
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_MESSAGE_SOURCE_H */
diff --git a/gnuradio-core/src/lib/io/gr_message_source.i b/gnuradio-core/src/lib/io/gr_message_source.i
new file mode 100644
index 0000000000..369112eff4
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_source.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,message_source);
+
+gr_message_source_sptr gr_make_message_source (size_t itemsize, int msgq_limit=0);
+
+class gr_message_source : public gr_sync_block
+{
+ protected:
+ gr_message_source (size_t itemsize, int msgq_limit);
+
+ public:
+ ~gr_message_source ();
+
+ gr_msg_queue_sptr msgq() const;
+};
diff --git a/gnuradio-core/src/lib/io/gr_oscope_guts.cc b/gnuradio-core/src/lib/io/gr_oscope_guts.cc
new file mode 100644
index 0000000000..6636fff1c7
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_oscope_guts.cc
@@ -0,0 +1,382 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_oscope_guts.h>
+#include <stdexcept>
+#include <stdio.h>
+#include <algorithm>
+#include <unistd.h>
+#include <math.h>
+#include <assert.h>
+
+static const int OUTPUT_RECORD_SIZE = 2048; // must be power of 2
+
+static inline int
+wrap_bi (int buffer_index) // wrap buffer index
+{
+ return buffer_index & (OUTPUT_RECORD_SIZE - 1);
+}
+
+static inline int
+incr_bi (int buffer_index) // increment buffer index
+{
+ return wrap_bi (buffer_index + 1);
+}
+
+static inline int
+decr_bi (int buffer_index) // decrement buffer index
+{
+ return wrap_bi (buffer_index - 1);
+}
+
+gr_oscope_guts::gr_oscope_guts (int nchannels, double sample_rate, gr_msg_queue_sptr msgq)
+ : d_nchannels (nchannels),
+ d_msgq (msgq),
+ d_trigger_mode (gr_TRIG_POS_SLOPE),
+ d_trigger_channel (0),
+ d_sample_rate (sample_rate),
+ d_update_rate (20),
+ d_trigger_level (0),
+ d_obi (0),
+ d_state (LOOK_FOR_TRIGGER),
+ d_decimator_count (0),
+ d_decimator_count_init (1),
+ d_hold_off_count (0),
+ d_hold_off_count_init (0),
+ d_post_trigger_count (0),
+ d_post_trigger_count_init (OUTPUT_RECORD_SIZE/2),
+ d_prev_sample (0)
+{
+ if (d_nchannels > MAX_CHANNELS){
+ fprintf (stderr, "gr_oscope_guts: too many channels. MAX_CHANNELS = %d\n", MAX_CHANNELS);
+ throw std::runtime_error ("too many channels");
+ }
+
+ for (int i = 0; i < MAX_CHANNELS; i++)
+ d_buffer[i] = 0;
+
+ for (int i = 0; i < d_nchannels; i++)
+ d_buffer[i] = new float [OUTPUT_RECORD_SIZE];
+
+ update_rate_or_decimation_changed ();
+ enter_look_for_trigger ();
+}
+
+gr_oscope_guts::~gr_oscope_guts ()
+{
+ for (int i = 0; i < MAX_CHANNELS; i++)
+ delete [] d_buffer[i];
+}
+
+// MANIPULATORS
+
+// \p channel_data points to nchannels float values. These are the values
+// for each channel at this sample time.
+
+void
+gr_oscope_guts::process_sample (const float *channel_data)
+{
+ d_decimator_count--;
+ if (d_decimator_count > 0)
+ return;
+
+ d_decimator_count = d_decimator_count_init;
+
+ for (int i = 0; i < d_nchannels; i++)
+ d_buffer[i][d_obi] = channel_data[i]; // copy data into buffer
+
+ int trigger = 0;
+
+ switch (d_state){
+ case HOLD_OFF:
+ d_hold_off_count--;
+ if (d_hold_off_count <= 0)
+ enter_look_for_trigger ();
+ break;
+
+ case LOOK_FOR_TRIGGER:
+ trigger = found_trigger (d_buffer[d_trigger_channel][d_obi]);
+ if (trigger != 0){
+ enter_post_trigger ();
+ if (trigger < 0) // previous sample was closer
+ d_post_trigger_count--;
+ }
+ break;
+
+ case POST_TRIGGER:
+ d_post_trigger_count--;
+ if (d_post_trigger_count <= 0){
+ write_output_records ();
+ enter_hold_off ();
+ }
+ break;
+
+ default:
+ assert (0);
+ }
+
+ d_obi = incr_bi (d_obi);
+}
+
+/*
+ * Functions called on state entry
+ */
+
+void
+gr_oscope_guts::enter_hold_off ()
+{
+ d_state = HOLD_OFF;
+ d_hold_off_count = d_hold_off_count_init;
+}
+
+void
+gr_oscope_guts::enter_look_for_trigger ()
+{
+ d_state = LOOK_FOR_TRIGGER;
+ d_prev_sample = d_buffer[d_trigger_channel][d_obi];
+}
+
+void
+gr_oscope_guts::enter_post_trigger ()
+{
+ d_state = POST_TRIGGER;
+ d_post_trigger_count = d_post_trigger_count_init;
+}
+
+// ----------------------------------------------------------------
+// returns 0 if no trigger found.
+// returns +1 if this sample is the trigger point
+// returns -1 if the previous sample is the trigger point
+
+int
+gr_oscope_guts::found_trigger (float new_sample)
+{
+ float prev_sample = d_prev_sample;
+ d_prev_sample = new_sample;
+ bool trig;
+
+ switch (d_trigger_mode){
+
+ case gr_TRIG_AUTO: // always trigger
+ return +1;
+
+ case gr_TRIG_POS_SLOPE:
+ trig = prev_sample < d_trigger_level && new_sample >= d_trigger_level;
+ if (trig){
+ if (fabs (prev_sample - d_trigger_level) < fabs (new_sample - d_trigger_level))
+ return -1;
+ else
+ return +1;
+ }
+ return 0;
+
+ case gr_TRIG_NEG_SLOPE:
+ trig = prev_sample > d_trigger_level && new_sample <= d_trigger_level;
+ if (trig){
+ if (fabs (prev_sample - d_trigger_level) < fabs (new_sample - d_trigger_level))
+ return -1;
+ else
+ return +1;
+ }
+ return 0;
+
+ default:
+ assert (0);
+ return 0;
+ }
+}
+
+// ----------------------------------------------------------------
+// write output records (duh!)
+
+void
+gr_oscope_guts::write_output_records ()
+{
+ // if the output queue if full, drop the data on the ground.
+ if (d_msgq->full_p())
+ return;
+
+ // Build a message to hold the output records
+ gr_message_sptr msg =
+ gr_make_message(0, // msg type
+ d_nchannels, // arg1 for other side
+ OUTPUT_RECORD_SIZE, // arg2 for other side
+ d_nchannels * OUTPUT_RECORD_SIZE * sizeof(float)); // sizeof payload
+
+ float *out = (float *)msg->msg(); // get pointer to raw message buffer
+
+ for (int ch = 0; ch < d_nchannels; ch++){
+ // note that d_obi points at the oldest sample in the buffer
+ for (int i = 0; i < OUTPUT_RECORD_SIZE; i++)
+ out[i] = d_buffer[ch][wrap_bi(d_obi + i)];
+
+ out += OUTPUT_RECORD_SIZE;
+ }
+
+ d_msgq->handle(msg); // send the msg
+}
+
+// ----------------------------------------------------------------
+
+bool
+gr_oscope_guts::set_update_rate (double update_rate)
+{
+ d_update_rate = std::min (std::max (1./10., update_rate), d_sample_rate);
+ update_rate_or_decimation_changed ();
+ return true;
+}
+
+bool
+gr_oscope_guts::set_decimation_count (int decimator_count)
+{
+ decimator_count = std::max (1, decimator_count);
+ d_decimator_count_init = decimator_count;
+ update_rate_or_decimation_changed ();
+ return true;
+}
+
+bool
+gr_oscope_guts::set_sample_rate(double sample_rate)
+{
+ d_sample_rate = sample_rate;
+ return set_update_rate(update_rate());
+}
+
+
+void
+gr_oscope_guts::update_rate_or_decimation_changed ()
+{
+ d_hold_off_count_init =
+ (int) rint (d_sample_rate / d_update_rate / d_decimator_count_init);
+}
+
+bool
+gr_oscope_guts::set_trigger_channel (int channel)
+{
+ if (channel >= 0 && channel < d_nchannels){
+ d_trigger_channel = channel;
+ trigger_changed ();
+ return true;
+ }
+
+ return false;
+}
+
+bool
+gr_oscope_guts::set_trigger_mode (gr_trigger_mode mode)
+{
+ switch (mode){
+ case gr_TRIG_POS_SLOPE:
+ case gr_TRIG_NEG_SLOPE:
+ case gr_TRIG_AUTO:
+ d_trigger_mode = mode;
+ trigger_changed ();
+ return true;
+ }
+ return false;
+}
+
+bool
+gr_oscope_guts::set_trigger_level (double trigger_level)
+{
+ d_trigger_level = trigger_level;
+ trigger_changed ();
+ return true;
+}
+
+bool
+gr_oscope_guts::set_trigger_level_auto ()
+{
+ // find the level 1/2 way between the min and the max
+
+ float min_v = d_buffer[d_trigger_channel][0];
+ float max_v = d_buffer[d_trigger_channel][0];
+
+ for (int i = 1; i < OUTPUT_RECORD_SIZE; i++){
+ min_v = std::min (min_v, d_buffer[d_trigger_channel][i]);
+ max_v = std::max (max_v, d_buffer[d_trigger_channel][i]);
+ }
+
+ d_trigger_level = (min_v + max_v) * 0.5;
+ trigger_changed ();
+ return true;
+}
+
+void
+gr_oscope_guts::trigger_changed ()
+{
+ // d_prev_sample = d_buffer[d_trigger_channel][decr_bi(d_obi)];
+ enter_look_for_trigger ();
+}
+
+// ACCESSORS
+
+int
+gr_oscope_guts::num_channels () const
+{
+ return d_nchannels;
+}
+
+double
+gr_oscope_guts::sample_rate () const
+{
+ return d_sample_rate;
+}
+
+double
+gr_oscope_guts::update_rate () const
+{
+ return d_update_rate;
+}
+
+int
+gr_oscope_guts::get_decimation_count () const
+{
+ return d_decimator_count_init;
+}
+
+int
+gr_oscope_guts::get_trigger_channel () const
+{
+ return d_trigger_channel;
+}
+
+gr_trigger_mode
+gr_oscope_guts::get_trigger_mode () const
+{
+ return d_trigger_mode;
+}
+
+double
+gr_oscope_guts::get_trigger_level () const
+{
+ return d_trigger_level;
+}
+
+int
+gr_oscope_guts::get_samples_per_output_record () const
+{
+ return OUTPUT_RECORD_SIZE;
+}
diff --git a/gnuradio-core/src/lib/io/gr_oscope_guts.h b/gnuradio-core/src/lib/io/gr_oscope_guts.h
new file mode 100644
index 0000000000..4094a65308
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_oscope_guts.h
@@ -0,0 +1,116 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef INCLUDED_GR_OSCOPE_GUTS_H
+#define INCLUDED_GR_OSCOPE_GUTS_H
+
+#include <gr_trigger_mode.h>
+#include <gr_msg_queue.h>
+
+/*!
+ * \brief guts of oscilloscope trigger and buffer module
+ *
+ * This module processes sets of samples provided the \p process_sample
+ * method. When appropriate given the updateRate, sampleRate and
+ * trigger conditions, process_sample will periodically write output
+ * records of captured data to output_fd. For each trigger event,
+ * nchannels records will be written. Each record consists of
+ * get_samples_per_output_record binary floats. The trigger instant
+ * occurs at the 1/2 way point in the buffer. Thus, output records
+ * consist of 50% pre-trigger data and 50% post-trigger data.
+ */
+
+class gr_oscope_guts {
+private:
+ static const int MAX_CHANNELS = 16;
+ enum scope_state { HOLD_OFF, LOOK_FOR_TRIGGER, POST_TRIGGER };
+
+ int d_nchannels; // how many channels
+ gr_msg_queue_sptr d_msgq; // message queue we stuff output records into
+ gr_trigger_mode d_trigger_mode;
+ int d_trigger_channel; // which channel to watch for trigger condition
+ double d_sample_rate; // input sample rate in Hz
+ double d_update_rate; // approx freq to produce an output record (Hz)
+ double d_trigger_level;
+
+ int d_obi; // output buffer index
+ float *d_buffer[MAX_CHANNELS];
+
+ scope_state d_state;
+ int d_decimator_count;
+ int d_decimator_count_init;
+ int d_hold_off_count;
+ int d_hold_off_count_init;
+ int d_post_trigger_count;
+ int d_post_trigger_count_init;
+ float d_prev_sample; // used for trigger checking
+
+ // NOT IMPLEMENTED
+ gr_oscope_guts (const gr_oscope_guts &rhs); // no copy constructor
+ gr_oscope_guts &operator= (const gr_oscope_guts &rhs); // no assignment operator
+
+ void trigger_changed ();
+ void update_rate_or_decimation_changed ();
+ int found_trigger (float sample); // returns -1, 0, +1
+ void write_output_records ();
+
+ void enter_hold_off (); // called on state entry
+ void enter_look_for_trigger ();
+ void enter_post_trigger ();
+
+public:
+ // CREATORS
+ gr_oscope_guts (int nchannels, double sample_rate, gr_msg_queue_sptr msgq);
+ ~gr_oscope_guts ();
+
+ // MANIPULATORS
+
+ /*!
+ * \p channel_data points to nchannels float values. These are the values
+ * for each channel at this sample time.
+ */
+ void process_sample (const float *channel_data);
+
+ bool set_update_rate (double update_rate);
+ bool set_decimation_count (int decimation_count);
+ bool set_trigger_channel (int channel);
+ bool set_trigger_mode (gr_trigger_mode mode);
+ bool set_trigger_level (double trigger_level);
+ bool set_trigger_level_auto (); // set to 50% level
+ bool set_sample_rate(double sample_rate);
+
+
+ // ACCESSORS
+ int num_channels () const;
+ double sample_rate () const;
+ double update_rate () const;
+ int get_decimation_count () const;
+ int get_trigger_channel () const;
+ gr_trigger_mode get_trigger_mode () const;
+ double get_trigger_level () const;
+
+ // # of samples written to each output record.
+ int get_samples_per_output_record () const;
+};
+
+#endif /* INCLUDED_GR_OSCOPE_GUTS_H */
diff --git a/gnuradio-core/src/lib/io/gr_oscope_sink.i b/gnuradio-core/src/lib/io/gr_oscope_sink.i
new file mode 100644
index 0000000000..ea8419909e
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_oscope_sink.i
@@ -0,0 +1,79 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+enum gr_trigger_mode {
+ gr_TRIG_AUTO, // auto trigger (on anything)
+ gr_TRIG_POS_SLOPE, // trigger on positive slope across trigger level
+ gr_TRIG_NEG_SLOPE // trigger on negative slope across trigger level
+};
+
+// GR_SWIG_BLOCK_MAGIC(gr,oscope_sink_x)
+
+%ignore gr_oscope_sink_x;
+class gr_oscope_sink_x : public gr_sync_block
+{
+ protected:
+ gr_oscope_sink_x (const std::string name,
+ gr_io_signature_sptr input_sig,
+ double sample_rate);
+
+ public:
+ ~gr_oscope_sink_x ();
+
+ bool set_update_rate (double update_rate);
+ bool set_decimation_count (int decimation_count);
+ bool set_trigger_channel (int channel);
+ bool set_trigger_mode (gr_trigger_mode mode);
+ bool set_trigger_level (double trigger_level);
+ bool set_trigger_level_auto (); // set to 50% level
+ bool set_sample_rate(double sample_rate);
+
+ // ACCESSORS
+ int num_channels () const;
+ double sample_rate () const;
+ double update_rate () const;
+ int get_decimation_count () const;
+ int get_trigger_channel () const;
+ gr_trigger_mode get_trigger_mode () const;
+ double get_trigger_level () const;
+
+ // # of samples written to each output record.
+ int get_samples_per_output_record () const;
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(gr,oscope_sink_f)
+
+gr_oscope_sink_f_sptr
+gr_make_oscope_sink_f (double sample_rate, gr_msg_queue_sptr msgq);
+
+class gr_oscope_sink_f : public gr_oscope_sink_x
+{
+private:
+ gr_oscope_sink_f (double sample_rate, gr_msg_queue_sptr msgq);
+
+public:
+ ~gr_oscope_sink_f ();
+};
+
+// ----------------------------------------------------------------
diff --git a/gnuradio-core/src/lib/io/gr_oscope_sink_f.cc b/gnuradio-core/src/lib/io/gr_oscope_sink_f.cc
new file mode 100644
index 0000000000..b505381da3
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_oscope_sink_f.cc
@@ -0,0 +1,80 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_oscope_sink_f.h>
+#include <gr_io_signature.h>
+#include <gr_oscope_guts.h>
+
+
+gr_oscope_sink_f_sptr
+gr_make_oscope_sink_f (double sampling_rate, gr_msg_queue_sptr msgq)
+{
+ return gr_oscope_sink_f_sptr (new gr_oscope_sink_f (sampling_rate, msgq));
+}
+
+
+gr_oscope_sink_f::gr_oscope_sink_f (double sampling_rate, gr_msg_queue_sptr msgq)
+ : gr_oscope_sink_x ("oscope_sink_f",
+ gr_make_io_signature (1, MAX_CHANNELS, sizeof (float)),
+ sampling_rate),
+ d_msgq(msgq)
+{
+}
+
+
+bool
+gr_oscope_sink_f::check_topology (int ninputs, int noutputs)
+{
+ delete d_guts;
+ d_guts = 0;
+ d_guts = new gr_oscope_guts (ninputs, d_sampling_rate, d_msgq);
+ return true;
+}
+
+
+gr_oscope_sink_f::~gr_oscope_sink_f ()
+{
+}
+
+int
+gr_oscope_sink_f::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ int ni = input_items.size ();
+ float tmp[MAX_CHANNELS];
+
+ for (int i = 0; i < noutput_items; i++){
+
+ // FIXME for now, copy the data. Fix later if reqd
+ for (int ch = 0; ch < ni; ch++)
+ tmp[ch] = ((const float *) input_items[ch])[i];
+
+ d_guts->process_sample (tmp);
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/io/gr_oscope_sink_f.h b/gnuradio-core/src/lib/io/gr_oscope_sink_f.h
new file mode 100644
index 0000000000..7b92a78500
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_oscope_sink_f.h
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_OSCOPE_SINK_F_H
+#define INCLUDED_GR_OSCOPE_SINK_F_H
+
+#include <gr_oscope_sink_x.h>
+#include <gr_msg_queue.h>
+
+class gr_oscope_sink_f;
+typedef boost::shared_ptr<gr_oscope_sink_x> gr_oscope_sink_f_sptr;
+
+gr_oscope_sink_f_sptr gr_make_oscope_sink_f (double sampling_rate, gr_msg_queue_sptr msgq);
+
+
+/*!
+ * \brief Building block for python oscilloscope module.
+ * \ingroup sink
+ *
+ * Accepts 1 to 16 float streams.
+ */
+class gr_oscope_sink_f : public gr_oscope_sink_x
+{
+public:
+ static const int MAX_CHANNELS = 16;
+
+private:
+ friend gr_oscope_sink_f_sptr
+ gr_make_oscope_sink_f (double sampling_rate, gr_msg_queue_sptr msgq);
+
+ gr_oscope_sink_f (double sampling_rate, gr_msg_queue_sptr msgq);
+
+ gr_msg_queue_sptr d_msgq;
+
+ public:
+ ~gr_oscope_sink_f ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ bool check_topology (int ninputs, int noutputs);
+};
+
+#endif /* INCLUDED_GR_OSCOPE_SINK_F_H */
+
diff --git a/gnuradio-core/src/lib/io/gr_oscope_sink_x.cc b/gnuradio-core/src/lib/io/gr_oscope_sink_x.cc
new file mode 100644
index 0000000000..51c28678e8
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_oscope_sink_x.cc
@@ -0,0 +1,138 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_oscope_sink_x.h>
+#include <gr_io_signature.h>
+#include <gr_oscope_guts.h>
+
+
+gr_oscope_sink_x::gr_oscope_sink_x (const std::string name,
+ gr_io_signature_sptr input_sig,
+ double sampling_rate)
+ : gr_sync_block (name, input_sig, gr_make_io_signature (0, 0, 0)),
+ d_sampling_rate (sampling_rate), d_guts (0)
+{
+}
+
+gr_oscope_sink_x::~gr_oscope_sink_x ()
+{
+ delete d_guts;
+}
+
+// ----------------------------------------------------------------
+
+bool
+gr_oscope_sink_x::set_update_rate (double update_rate)
+{
+ return d_guts->set_update_rate (update_rate);
+}
+
+bool
+gr_oscope_sink_x::set_decimation_count (int decimation_count)
+{
+ return d_guts->set_decimation_count (decimation_count);
+}
+
+bool
+gr_oscope_sink_x::set_trigger_channel (int channel)
+{
+ return d_guts->set_trigger_channel (channel);
+}
+
+bool
+gr_oscope_sink_x::set_trigger_mode (gr_trigger_mode mode)
+{
+ return d_guts->set_trigger_mode (mode);
+}
+
+bool
+gr_oscope_sink_x::set_trigger_level (double trigger_level)
+{
+ return d_guts->set_trigger_level (trigger_level);
+}
+
+
+bool
+gr_oscope_sink_x::set_trigger_level_auto ()
+{
+ return d_guts->set_trigger_level_auto ();
+}
+
+bool
+gr_oscope_sink_x::set_sample_rate (double sample_rate)
+{
+ return d_guts->set_sample_rate (sample_rate);
+}
+
+// ACCESSORS
+
+int
+gr_oscope_sink_x::num_channels () const
+{
+ return d_guts->num_channels ();
+}
+
+double
+gr_oscope_sink_x::sample_rate () const
+{
+ return d_guts->sample_rate ();
+}
+
+double
+gr_oscope_sink_x::update_rate () const
+{
+ return d_guts->update_rate ();
+}
+
+int
+gr_oscope_sink_x::get_decimation_count () const
+{
+ return d_guts->get_decimation_count ();
+}
+
+int
+gr_oscope_sink_x::get_trigger_channel () const
+{
+ return d_guts->get_trigger_channel ();
+}
+
+gr_trigger_mode
+gr_oscope_sink_x::get_trigger_mode () const
+{
+ return d_guts->get_trigger_mode ();
+}
+
+double
+gr_oscope_sink_x::get_trigger_level () const
+{
+ return d_guts->get_trigger_level ();
+}
+
+int
+gr_oscope_sink_x::get_samples_per_output_record () const
+{
+ return d_guts->get_samples_per_output_record ();
+}
diff --git a/gnuradio-core/src/lib/io/gr_oscope_sink_x.h b/gnuradio-core/src/lib/io/gr_oscope_sink_x.h
new file mode 100644
index 0000000000..45cccc0d46
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_oscope_sink_x.h
@@ -0,0 +1,73 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_OSCOPE_SINK_X_H
+#define INCLUDED_GR_OSCOPE_SINK_X_H
+
+#include <gr_sync_block.h>
+#include <gr_trigger_mode.h>
+
+class gr_oscope_guts;
+
+/*!
+ * \brief Abstract class for python oscilloscope module.
+ * \ingroup sink
+ *
+ * Don't instantiate this. Use gr_oscope_sink_f or gr_oscope_sink_c instead.
+ */
+class gr_oscope_sink_x : public gr_sync_block
+{
+protected:
+ double d_sampling_rate;
+ gr_oscope_guts *d_guts;
+
+ gr_oscope_sink_x (const std::string name,
+ gr_io_signature_sptr input_sig,
+ double sampling_rate);
+
+public:
+ ~gr_oscope_sink_x ();
+
+ bool set_update_rate (double update_rate);
+ bool set_decimation_count (int decimation_count);
+ bool set_trigger_channel (int channel);
+ bool set_trigger_mode (gr_trigger_mode mode);
+ bool set_trigger_level (double trigger_level);
+ bool set_trigger_level_auto (); // set to 50% level
+ bool set_sample_rate(double sample_rate);
+
+
+ // ACCESSORS
+ int num_channels () const;
+ double sample_rate () const;
+ double update_rate () const;
+ int get_decimation_count () const;
+ int get_trigger_channel () const;
+ gr_trigger_mode get_trigger_mode () const;
+ double get_trigger_level () const;
+
+ // # of samples written to each output record.
+ int get_samples_per_output_record () const;
+
+};
+
+#endif /* INCLUDED_GR_OSCOPE_SINK_X_H */
diff --git a/gnuradio-core/src/lib/io/gr_trigger_mode.h b/gnuradio-core/src/lib/io/gr_trigger_mode.h
new file mode 100644
index 0000000000..0928c6a342
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_trigger_mode.h
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_TRIGGER_MODE_H
+#define INCLUDED_GR_TRIGGER_MODE_H
+
+enum gr_trigger_mode {
+ gr_TRIG_AUTO, // auto trigger (on anything)
+ gr_TRIG_POS_SLOPE, // trigger on positive slope across trigger level
+ gr_TRIG_NEG_SLOPE // trigger on negative slope across trigger level
+};
+
+#endif /* INCLUDED_GR_TRIGGER_MODE_H */
diff --git a/gnuradio-core/src/lib/io/gri_logger.cc b/gnuradio-core/src/lib/io/gri_logger.cc
new file mode 100644
index 0000000000..a1bdfb0e28
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gri_logger.cc
@@ -0,0 +1,173 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gri_logger.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdexcept>
+#include <boost/weak_ptr.hpp>
+
+
+/*
+ * This class creates the thread that reads from the ringbuffer and
+ * and writes to the file. This is opaque to the user.
+ */
+class gri_log_poster : public omni_thread
+{
+ FILE *d_fp;
+ gr_buffer_sptr d_writer;
+ gr_buffer_reader_sptr d_reader;
+ omni_semaphore d_ringbuffer_ready;
+ volatile bool d_time_to_die;
+ volatile bool d_writer_overrun;
+
+ virtual void* run_undetached(void * arg);
+
+public:
+ gri_log_poster(const char *filename);
+ ~gri_log_poster();
+
+ void kill() { d_time_to_die = true; post(); }
+ gr_buffer_sptr writer() const { return d_writer; }
+ void post() { d_ringbuffer_ready.post(); }
+ void note_writer_overrun() { d_writer_overrun = true; }
+};
+
+gri_log_poster::gri_log_poster(const char *filename)
+ : omni_thread(),
+ d_ringbuffer_ready(1, 1), // binary semaphore
+ d_time_to_die(false),
+ d_writer_overrun(false)
+{
+ if ((d_fp = fopen(filename, "w")) == 0){
+ perror (filename);
+ throw std::runtime_error("can't open file");
+ }
+
+ // Create a 1MB buffer.
+ d_writer = gr_make_buffer(1 * 1024 * 1024, sizeof(unsigned char));
+ d_reader = gr_buffer_add_reader(d_writer, 0);
+
+ start_undetached(); // start the thread
+}
+
+gri_log_poster::~gri_log_poster()
+{
+ if (d_fp != 0){
+ fclose(d_fp);
+ d_fp = 0;
+ }
+}
+
+/*
+ * This is the body of the logging thread.
+ */
+void *
+gri_log_poster::run_undetached(void *arg)
+{
+ int nbytes;
+
+ //fprintf(stderr, "Enter: run_undetached!\n");
+
+ while (!d_time_to_die){
+ while ((nbytes = d_reader->items_available()) > 0){
+ fwrite(d_reader->read_pointer(), 1, nbytes, d_fp);
+ d_reader->update_read_pointer(nbytes);
+ }
+ fflush(d_fp);
+ d_ringbuffer_ready.wait();
+
+ if (d_writer_overrun){
+ fputs(">>>>> gri_logger: writer overrun. Info lost <<<<<\n", d_fp);
+ d_writer_overrun = false;
+ }
+ }
+
+ // fprintf(stderr, "Exit: run_undetached!\n");
+ return 0;
+}
+
+// ------------------------------------------------------------------------
+
+static boost::weak_ptr<gri_logger> s_singleton; // weak pointer IQ test ;-)
+static omni_mutex s_singleton_mutex;
+
+gri_logger_sptr
+gri_logger::singleton()
+{
+ omni_mutex_lock l(s_singleton_mutex);
+ gri_logger_sptr r;
+
+ if (r = s_singleton.lock())
+ return r;
+
+ r = gri_logger_sptr(new gri_logger("gri_logger.log"));
+ s_singleton = r;
+ return r;
+}
+
+
+gri_logger::gri_logger(const char *filename)
+{
+ d_poster = new gri_log_poster(filename);
+}
+
+gri_logger::~gri_logger()
+{
+ d_poster->kill();
+ d_poster->join(NULL);
+}
+
+void
+gri_logger::write(const void *buf, size_t count)
+{
+ omni_mutex_lock l(d_write_mutex);
+ gr_buffer_sptr writer = d_poster->writer();
+
+ // either write it all, or drop it on the ground
+ if (count <= (size_t) writer->space_available()){
+ memcpy(writer->write_pointer(), buf, count);
+ writer->update_write_pointer(count);
+ d_poster->post();
+ }
+ else {
+ d_poster->note_writer_overrun();
+ }
+}
+
+void
+gri_logger::printf(const char *format, ...)
+{
+ va_list ap;
+ char buf[4096];
+ int n;
+
+ va_start(ap, format);
+ n = vsnprintf(buf, sizeof(buf), format, ap);
+ va_end(ap);
+ if (n > -1 && n < (ssize_t) sizeof(buf))
+ write(buf, n);
+}
diff --git a/gnuradio-core/src/lib/io/gri_logger.h b/gnuradio-core/src/lib/io/gri_logger.h
new file mode 100644
index 0000000000..ecbd3141ee
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gri_logger.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GRI_LOGGER_H
+#define INCLUDED_GRI_LOGGER_H
+
+#include <stddef.h>
+#include <omnithread.h>
+#include <gr_buffer.h>
+
+class gri_log_poster;
+class gri_logger;
+typedef boost::shared_ptr<gri_logger> gri_logger_sptr;
+
+
+/*!
+ * \brief non-blocking logging to a file.
+ *
+ * In reality, this may block, but only for a bounded time.
+ * Trust me, it's safe to use from portaudio and JACK callbacks.
+ */
+class gri_logger
+{
+ gri_log_poster *d_poster;
+ omni_mutex d_write_mutex;
+
+public:
+ static gri_logger_sptr singleton();
+
+ gri_logger(const char *filename);
+ ~gri_logger();
+
+ void write(const void *buf, size_t count);
+ void printf(const char *format, ...);
+};
+
+#endif /* INCLUDED_GRI_LOGGER_H */
diff --git a/gnuradio-core/src/lib/io/i2c.cc b/gnuradio-core/src/lib/io/i2c.cc
new file mode 100644
index 0000000000..9b9fbcd156
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "i2c.h"
+
+i2c::~i2c ()
+{
+ // NOP
+}
diff --git a/gnuradio-core/src/lib/io/i2c.h b/gnuradio-core/src/lib/io/i2c.h
new file mode 100644
index 0000000000..88b3c91354
--- /dev/null
+++ b/gnuradio-core/src/lib/io/i2c.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_I2C_H
+#define INCLUDED_I2C_H
+
+#include <boost/shared_ptr.hpp>
+
+class i2c;
+typedef boost::shared_ptr<i2c> i2c_sptr;
+
+/*!
+ * \brief abstract class for controlling i2c bus
+ */
+class i2c {
+ public:
+
+ i2c () {}
+ virtual ~i2c ();
+
+ //! \returns true iff successful
+ virtual bool write (int addr, const unsigned char *buf, int nbytes) = 0;
+
+ //! \returns number of bytes read or -1 if error
+ virtual int read (int addr, unsigned char *buf, int max_bytes) = 0;
+};
+
+#endif /* INCLUDED_I2C_H */
+
diff --git a/gnuradio-core/src/lib/io/i2c_bbio.cc b/gnuradio-core/src/lib/io/i2c_bbio.cc
new file mode 100644
index 0000000000..8f3839768d
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "i2c_bbio.h"
+
+i2c_bbio::~i2c_bbio ()
+{
+ // NOP
+}
+
diff --git a/gnuradio-core/src/lib/io/i2c_bbio.h b/gnuradio-core/src/lib/io/i2c_bbio.h
new file mode 100644
index 0000000000..f0ea3b6646
--- /dev/null
+++ b/gnuradio-core/src/lib/io/i2c_bbio.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_I2C_BBIO_H
+#define INCLUDED_I2C_BBIO_H
+
+#include <boost/shared_ptr.hpp>
+
+class i2c_bbio;
+typedef boost::shared_ptr<i2c_bbio> i2c_bbio_sptr;
+
+
+/*!
+ * \brief abstract class that implements bit banging i/o for i2c bus.
+ */
+class i2c_bbio {
+ public:
+
+ i2c_bbio () {}
+ virtual ~i2c_bbio ();
+
+ virtual void set_scl (bool state) = 0;
+ virtual void set_sda (bool state) = 0;
+ virtual bool get_sda () = 0;
+
+ virtual void lock () = 0;
+ virtual void unlock () = 0;
+};
+
+#endif /* INCLUDED_I2C_BBIO_H */
diff --git a/gnuradio-core/src/lib/io/i2c_bbio_pp.cc b/gnuradio-core/src/lib/io/i2c_bbio_pp.cc
new file mode 100644
index 0000000000..125f01c339
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "i2c_bbio_pp.h"
+#include "microtune_eval_board_defs.h"
+
+i2c_bbio_pp::i2c_bbio_pp (ppio_sptr pp)
+{
+ d_pp = pp;
+ d_pp->lock ();
+ d_pp->write_control (d_pp->read_control () & ~UT_CP_MUST_BE_ZERO); // output, no interrupts
+ d_pp->unlock ();
+}
+
+i2c_bbio_sptr
+make_i2c_bbio_pp (ppio_sptr pp)
+{
+ return i2c_bbio_sptr (new i2c_bbio_pp (pp));
+}
+
+void
+i2c_bbio_pp::set_scl (bool state)
+{
+ int r = d_pp->read_control();
+
+ if (!state){ // active low
+ d_pp->write_control (r | UT_CP_TUNER_SCL);
+ }
+ else {
+ d_pp->write_control (r & ~UT_CP_TUNER_SCL);
+ }
+ d_pp->read_control (); // use for 1us delay
+ d_pp->read_control (); // use for 1us delay
+}
+
+void
+i2c_bbio_pp::set_sda (bool state)
+{
+ int r = d_pp->read_data ();
+
+ if (!state){ // active low
+ d_pp->write_data (r | UT_DP_TUNER_SDA_OUT);
+ }
+ else {
+ d_pp->write_data (r & ~UT_DP_TUNER_SDA_OUT);
+ }
+ d_pp->read_data (); // use for 1us delay
+ d_pp->read_data (); // use for 1us delay
+}
+
+bool
+i2c_bbio_pp::get_sda ()
+{
+ int r = d_pp->read_status ();
+ return (r & UT_SP_TUNER_SDA_IN) == 0; // eval board has an inverter on it
+}
+
+void
+i2c_bbio_pp::lock ()
+{
+ d_pp->lock ();
+}
+
+void
+i2c_bbio_pp::unlock ()
+{
+ d_pp->unlock ();
+}
diff --git a/gnuradio-core/src/lib/io/i2c_bbio_pp.h b/gnuradio-core/src/lib/io/i2c_bbio_pp.h
new file mode 100644
index 0000000000..25af0cf428
--- /dev/null
+++ b/gnuradio-core/src/lib/io/i2c_bbio_pp.h
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_I2C_BBIO_PP_H
+#define INCLUDED_I2C_BBIO_PP_H
+
+#include "i2c_bbio.h"
+#include "ppio.h"
+
+/*!
+ * \brief concrete class that bit bangs eval board i2c bus using parallel port
+ *
+ * This class talks to the i2c bus on the microtune eval board using
+ * the parallel port. This works for both the 4937 and 4702 boards.
+ */
+class i2c_bbio_pp : public i2c_bbio {
+ friend i2c_bbio_sptr make_i2c_bbio_pp (ppio_sptr pp);
+ i2c_bbio_pp (ppio_sptr pp);
+
+ public:
+
+ virtual void set_scl (bool state);
+ virtual void set_sda (bool state);
+ virtual bool get_sda ();
+
+ virtual void lock ();
+ virtual void unlock ();
+
+ private:
+ ppio_sptr d_pp;
+};
+
+i2c_bbio_sptr make_i2c_bbio_pp (ppio_sptr pp);
+
+
+#endif /* INCLUDED_I2C_BBIO_PP_H */
diff --git a/gnuradio-core/src/lib/io/i2c_bitbang.cc b/gnuradio-core/src/lib/io/i2c_bitbang.cc
new file mode 100644
index 0000000000..6bf37b604d
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "i2c_bitbang.h"
+
+i2c_bitbang::i2c_bitbang (i2c_bbio_sptr io)
+{
+ d_io = io;
+ d_io->lock ();
+
+ stop (); // get bus in known state
+
+ d_io->unlock ();
+}
+
+i2c_sptr
+make_i2c_bitbang (i2c_bbio_sptr io)
+{
+ return i2c_sptr (new i2c_bitbang (io));
+}
+
+
+// start:
+// entry: SCL = 1, SDA = 1
+// exit: SCL = 0, SDA = 0
+
+void
+i2c_bitbang::start ()
+{
+ set_sda (1);
+ set_scl (1);
+ set_sda (0); // SDA high -> low while SCL high
+ set_scl (0);
+}
+
+
+// stop:
+// entry: SCL = X, SDA = X
+// exit: SCL = 1, SDA = 1
+
+void
+i2c_bitbang::stop ()
+{
+ set_scl (0);
+ set_sda (0);
+ set_scl (1);
+ set_sda (1); // SDA low -> high while SCL high
+}
+
+
+// write_bit:
+// entry: SCL = 0, SDA = X
+// exit: SCL = 0, SDA = X
+
+void
+i2c_bitbang::write_bit (bool bit)
+{
+ set_sda (bit);
+ set_scl (1);
+ set_scl (0);
+}
+
+
+// write_byte:
+// entry: SCL = 0, SDA = X
+// exit: SCL = 0, SDA = 1
+
+bool
+i2c_bitbang::write_byte (char t)
+{
+ int i;
+ bool ack_bit;
+
+ for (i = 0; i < 8; i++){
+ write_bit (t & 0x80);
+ t <<= 1;
+ }
+
+ // clock #9. This is the ACK bit.
+
+ set_sda (1); // tristate SDA
+ set_scl (1);
+ ack_bit = get_sda (); // slave should pull SDA line low
+ set_scl (0);
+
+ return ack_bit == 0;
+}
+
+
+// write: the high level entry point...
+// entry: SCL = 1, SDA = 1
+// exit: SCL = 1, SDA = 1
+
+bool
+i2c_bitbang::write (int addr, const unsigned char *buf, int nbytes)
+{
+ bool ok = true;
+
+ d_io->lock ();
+ start ();
+ ok = write_byte ((addr << 1) | 0); // addr plus "read opcode"
+
+ for (int i = 0; i < nbytes; i++)
+ ok &= write_byte (buf[i]);
+
+ stop ();
+ d_io->unlock ();
+ return ok;
+}
+
+
+// read: the high level entry point...
+// entry: SCL = 1, SDA = 1
+// exit: SCL = 1, SDA = 1
+
+int
+i2c_bitbang::read (int addr, unsigned char *buf, int max_bytes)
+{
+ d_io->lock ();
+
+ // FIXME
+
+ d_io->unlock ();
+ return -1;
+}
diff --git a/gnuradio-core/src/lib/io/i2c_bitbang.h b/gnuradio-core/src/lib/io/i2c_bitbang.h
new file mode 100644
index 0000000000..5196cd2342
--- /dev/null
+++ b/gnuradio-core/src/lib/io/i2c_bitbang.h
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_I2C_BITBANG_H
+#define INCLUDED_I2C_BITBANG_H
+
+#include <i2c.h>
+#include <i2c_bbio.h>
+
+/*!
+ * \brief class for controlling i2c bus
+ */
+class i2c_bitbang : public i2c {
+ friend i2c_sptr make_i2c_bitbang (i2c_bbio_sptr io);
+ i2c_bitbang (i2c_bbio_sptr io);
+
+ public:
+ ~i2c_bitbang () {}
+
+ //! \returns true iff successful
+ bool write (int addr, const unsigned char *buf, int nbytes);
+
+ //! \returns number of bytes read or -1 if error
+ int read (int addr, unsigned char *buf, int max_bytes);
+
+
+private:
+ void start ();
+ void stop ();
+ void write_bit (bool bit);
+ bool write_byte (char byte);
+
+ void set_sda (bool bit) { d_io->set_sda (bit); }
+ void set_scl (bool bit) { d_io->set_scl (bit); }
+ bool get_sda () { return d_io->get_sda (); }
+
+ i2c_bbio_sptr d_io;
+};
+
+i2c_sptr make_i2c_bitbang (i2c_bbio_sptr io);
+
+#endif /* INCLUDED_I2C_BITBANG_H */
+
+
diff --git a/gnuradio-core/src/lib/io/io.i b/gnuradio-core/src/lib/io/io.i
new file mode 100644
index 0000000000..ae4ca26820
--- /dev/null
+++ b/gnuradio-core/src/lib/io/io.i
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+%{
+
+#include <gr_file_sink.h>
+#include <gr_file_source.h>
+#include <gr_file_descriptor_sink.h>
+#include <gr_file_descriptor_source.h>
+#include <microtune_4702_eval_board.h>
+#include <microtune_4937_eval_board.h>
+#include <sdr_1000.h>
+#include <gr_oscope_sink_x.h>
+#include <gr_oscope_sink_f.h>
+#include <ppio.h>
+#include <gr_message_source.h>
+#include <gr_message_sink.h>
+
+%}
+
+%include "gr_file_sink.i"
+%include "gr_file_source.i"
+%include "gr_file_descriptor_sink.i"
+%include "gr_file_descriptor_source.i"
+%include "microtune_xxxx_eval_board.i"
+%include "microtune_4702_eval_board.i"
+%include "microtune_4937_eval_board.i"
+%include "sdr_1000.i"
+%include "gr_oscope_sink.i"
+%include "ppio.i"
+%include "gr_message_source.i"
+%include "gr_message_sink.i"
+
diff --git a/gnuradio-core/src/lib/io/microtune_4702.cc b/gnuradio-core/src/lib/io/microtune_4702.cc
new file mode 100644
index 0000000000..9b180ff8be
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "microtune_4702.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include "i2c.h"
+
+static const double FIRST_IF = 36.00e6;
+
+// The tuner internally has 3 bands: VHF Low, VHF High & UHF.
+// These are the recommened boundaries
+static const double VHF_High_takeover = 174e6;
+static const double UHF_takeover = 470e6;
+
+static int PLL_I2C_ADDR = 0x60;
+
+static unsigned char
+control_byte_1 (bool prescaler, int reference_divisor)
+{
+ int c = 0x80;
+ //Note: Last two divider bits (bits 2 and 3 of this byte) determined later
+ if (prescaler)
+ c |= 0x10;
+
+ switch (reference_divisor){
+ case 2:
+ c |= 0x00; break;
+ case 4:
+ c |= 0x01; break;
+ case 8:
+ c |= 0x02; break;
+ case 16:
+ c |= 0x03; break;
+ case 32:
+ c |= 0x04; break;
+ case 64:
+ c |= 0x05; break;
+ case 128:
+ c |= 0x06; break;
+ case 256:
+ c |= 0x07; break;
+ case 24:
+ c |= 0x08; break;
+ case 5:
+ c |= 0x09; break;
+ case 10:
+ c |= 0x0A; break;
+ case 20:
+ c |= 0x0B; break;
+ case 40:
+ c |= 0x0C; break;
+ case 80:
+ c |= 0x0D; break;
+ case 160:
+ c |= 0x0E; break;
+ case 320:
+ c |= 0x0F; break;
+ default:
+ abort ();
+ }
+ return c;
+}
+
+static unsigned char
+control_byte_2 (double target_freq)
+{
+ int c;
+
+ if (target_freq < VHF_High_takeover) // VHF low
+ c = 0x8E;
+
+ else if (target_freq < UHF_takeover){ // VHF high
+ c = 0x05;
+ if (target_freq < 390e6)
+ c |= 0x40;
+ else
+ c |= 0x80;
+ }
+ else { // UHF
+ c = 0x03;
+ if (target_freq < 750e6)
+ c |= 0x80;
+ else
+ c |= 0xC0;
+ }
+
+ return c;
+}
+
+
+microtune_4702::microtune_4702 (i2c_sptr i2c, int i2c_addr)
+{
+ d_i2c = i2c;
+ d_i2c_addr = i2c_addr;
+ d_reference_divider = 320;
+ d_prescaler = false;
+}
+
+microtune_4702::~microtune_4702 ()
+{
+ // nop
+}
+
+/*!
+ * \brief select RF frequency to be tuned to output frequency.
+ * \p target_freq is the requested frequency in Hz, \p actual_freq
+ * is set to the actual frequency tuned. It takes about 100 ms
+ * for the PLL to settle.
+ *
+ * \returns true iff sucessful.
+ */
+bool
+microtune_4702::set_RF_freq (double target_freq, double *p_actual_freq)
+{
+ unsigned char buf[4];
+
+ double target_f_osc = target_freq + FIRST_IF;
+
+ double f_ref = 4e6 / d_reference_divider;
+
+ //int divisor = (int) ((target_f_osc + (f_ref * 4)) / (f_ref * 8));
+
+ long int divisor = (long int) (target_f_osc / f_ref);
+ double actual_freq = (f_ref * divisor) - FIRST_IF;
+ if (p_actual_freq != 0)
+ *p_actual_freq = actual_freq;
+
+ if ((divisor & ~0x1ffff) != 0) // >17 bit divisor
+ return false;
+
+ buf[0] = ((divisor & 0x07f00) >> 8) & 0xff; // DB1
+ buf[1] = divisor & 0xff; // DB2
+ buf[2] = control_byte_1 (d_prescaler, d_reference_divider);
+ buf[2] = (buf[2]|(((divisor & 0x18000) >> 10)) & 0xff);
+ buf[3] = control_byte_2 (target_freq);
+
+ printf ("%x\n", PLL_I2C_ADDR);
+//#if 0
+ printf ("set_RF_freq: target: %g MHz actual: %g MHz %02x %02x %02x %02x\n",
+ target_freq/1e6, actual_freq/1e6, buf[0], buf[1], buf[2], buf[3]);
+//#endif
+
+ return d_i2c->write (d_i2c_addr, buf, sizeof (buf));
+}
+
+/*!
+ * \returns true iff PLL is locked
+ */
+bool
+microtune_4702::pll_locked_p ()
+{
+ // FIXME
+ return true;
+}
+
+/*!
+ * \returns the output frequency of the tuner in Hz.
+ */
+double
+microtune_4702::get_output_freq ()
+{
+ return FIRST_IF;
+}
diff --git a/gnuradio-core/src/lib/io/microtune_4702.h b/gnuradio-core/src/lib/io/microtune_4702.h
new file mode 100644
index 0000000000..b5890774fa
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4702.h
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_MICROTUNE_4702_H
+#define INCLUDED_MICROTUNE_4702_H
+
+#include <microtune_xxxx.h>
+
+/*!
+ * \brief class for controlling microtune 4702 tuner module
+ */
+
+class microtune_4702 : public microtune_xxxx {
+public:
+ microtune_4702 (i2c_sptr i2c, int i2c_addr);
+
+ virtual ~microtune_4702 ();
+
+ /*!
+ * \brief select RF frequency to be tuned to output frequency.
+ * \p freq is the requested frequency in Hz, \p actual_freq
+ * is set to the actual frequency tuned. It takes about 100 ms
+ * for the PLL to settle.
+ *
+ * \returns true iff sucessful.
+ */
+ bool set_RF_freq (double freq, double *actual_freq);
+
+ /*!
+ * \returns true iff PLL is locked
+ */
+ bool pll_locked_p ();
+
+ /*!
+ * \returns the output frequency of the tuner in Hz.
+ */
+ double get_output_freq ();
+
+ private:
+
+ i2c_sptr d_i2c;
+ int d_i2c_addr;
+ int d_reference_divider;
+ bool d_prescaler; /* if set, higher charge pump current:
+ faster tuning, worse phase noise
+ for distance < 10kHz to the carrier */
+};
+
+#endif /* INCLUDED_MICROTUNE_4702_H */
+
diff --git a/gnuradio-core/src/lib/io/microtune_4702_eval_board.cc b/gnuradio-core/src/lib/io/microtune_4702_eval_board.cc
new file mode 100644
index 0000000000..88cf2b6a0c
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "microtune_4702_eval_board.h"
+#include "microtune_eval_board_defs.h"
+#include "ppio.h"
+#include "microtune_4702.h"
+
+static const int TUNER_I2C_ADDR = 0x60;
+
+microtune_4702_eval_board::microtune_4702_eval_board (int which_pp)
+ : microtune_xxxx_eval_board (which_pp)
+{
+ d_tuner = new microtune_4702 (d_i2c, TUNER_I2C_ADDR);
+}
+
+microtune_4702_eval_board::~microtune_4702_eval_board ()
+{
+ // default is OK
+}
+
+static const float RF_MIN_V = 1.0; // RF AGC control voltages
+static const float RF_MAX_V = 4.0;
+static const float IF_MIN_V = 2.0; // IF AGC control voltages
+static const float IF_MAX_V = 4.0;
+
+static const float MIN_AGC = 0; // bottom of synthetic range
+static const float MAX_AGC = 1000; // top of synthetic range
+
+static const float CUTOVER_POINT = 667;
+
+
+// linear is in the range MIN_AGC to MAX_AGC
+
+static float
+linear_to_RF_AGC_voltage (float linear)
+{
+ if (linear >= CUTOVER_POINT)
+ return RF_MAX_V;
+
+ float slope = (RF_MAX_V - RF_MIN_V) / CUTOVER_POINT;
+ return RF_MIN_V + linear * slope;
+}
+
+static float
+linear_to_IF_AGC_voltage (float linear)
+{
+ if (linear < CUTOVER_POINT)
+ return IF_MIN_V;
+
+ float slope = (IF_MAX_V - IF_MIN_V) / (MAX_AGC - CUTOVER_POINT);
+ return IF_MIN_V + (linear - CUTOVER_POINT) * slope;
+}
+
+void
+microtune_4702_eval_board::set_AGC (float v)
+{
+ if (v < MIN_AGC)
+ v = MIN_AGC;
+
+ if (v > MAX_AGC)
+ v = MAX_AGC;
+
+ float rf_agc_voltage = linear_to_RF_AGC_voltage (v);
+ float if_agc_voltage = linear_to_IF_AGC_voltage (v);
+
+ set_RF_AGC_voltage (rf_agc_voltage);
+ set_IF_AGC_voltage (if_agc_voltage);
+}
diff --git a/gnuradio-core/src/lib/io/microtune_4702_eval_board.h b/gnuradio-core/src/lib/io/microtune_4702_eval_board.h
new file mode 100644
index 0000000000..9fc2914edb
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4702_eval_board.h
@@ -0,0 +1,47 @@
+/* -*- C++ -*- */
+/*
+ * Copyright 2001,2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_MICROTUNE_4702_EVAL_BOARD_H
+#define INCLUDED_MICROTUNE_4702_EVAL_BOARD_H
+
+#include "microtune_xxxx_eval_board.h"
+
+/*!
+ * \brief control microtune 4702 eval board
+ */
+
+class microtune_4702_eval_board : public microtune_xxxx_eval_board {
+public:
+ microtune_4702_eval_board (int which_pp = 0);
+ ~microtune_4702_eval_board ();
+
+ /*!
+ * \brief set RF and IF AGC levels together (scale [0, 1000])
+ *
+ * This provides a simple linear interface for adjusting both
+ * the RF and IF gain in consort. This is the easy to use interface.
+ * 0 corresponds to minimum gain. 1000 corresponds to maximum gain.
+ */
+ virtual void set_AGC (float value_0_1000);
+};
+
+#endif /* INCLUDED_MICROTUNE_4702_EVAL_BOARD_H */
diff --git a/gnuradio-core/src/lib/io/microtune_4702_eval_board.i b/gnuradio-core/src/lib/io/microtune_4702_eval_board.i
new file mode 100644
index 0000000000..6205c93033
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+class microtune_4702_eval_board : public microtune_xxxx_eval_board {
+public:
+ microtune_4702_eval_board (int which_pp = 0);
+ ~microtune_4702_eval_board ();
+
+ /*!
+ * \brief set RF and IF AGC levels together (scale [0, 1000])
+ *
+ * This provides a simple linear interface for adjusting both
+ * the RF and IF gain in consort. This is the easy to use interface.
+ * 0 corresponds to minimum gain. 1000 corresponds to maximum gain.
+ */
+ virtual void set_AGC (float value_0_1000);
+};
diff --git a/gnuradio-core/src/lib/io/microtune_4937.cc b/gnuradio-core/src/lib/io/microtune_4937.cc
new file mode 100644
index 0000000000..c05f63c113
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "microtune_4937.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <i2c.h>
+
+static const double first_IF = 43.75e6;
+
+// The tuner internally has 3 bands: VHF Low, VHF High & UHF.
+// These are the recommened boundaries
+static const double VHF_High_takeover = 158e6;
+static const double UHF_takeover = 464e6;
+
+
+static unsigned char
+control_byte_1 (bool fast_tuning_p, int reference_divisor)
+{
+ int c = 0x88;
+
+ if (fast_tuning_p)
+ c |= 0x40;
+
+ switch (reference_divisor){
+ case 512:
+ c |= 0x3 << 1; break;
+ case 640:
+ c |= 0x0 << 1; break;
+ case 1024:
+ c |= 0x1 << 1; break;
+ default:
+ abort ();
+ }
+ return c;
+}
+
+static unsigned char
+control_byte_2 (double target_freq, bool shutdown_tx_PGA)
+{
+ int c;
+
+ if (target_freq < VHF_High_takeover) // VHF low
+ c = 0xa0;
+ else if (target_freq < UHF_takeover) // VHF high
+ c = 0x90;
+ else // UHF
+ c = 0x30;
+
+ if (shutdown_tx_PGA)
+ c |= 0x08;
+
+ return c;
+}
+
+microtune_4937::microtune_4937 (i2c_sptr i2c, int i2c_addr)
+{
+ d_i2c = i2c;
+ d_i2c_addr = i2c_addr;
+ d_reference_divider = 640;
+ d_fast_tuning_p = false;
+}
+
+microtune_4937::~microtune_4937 ()
+{
+ // nop
+}
+
+/*!
+ * \brief select RF frequency to be tuned to output frequency.
+ * \p target_freq is the requested frequency in Hz, \p actual_freq
+ * is set to the actual frequency tuned. It takes about 100 ms
+ * for the PLL to settle.
+ *
+ * \returns true iff sucessful.
+ */
+bool
+microtune_4937::set_RF_freq (double target_freq, double *p_actual_freq)
+{
+ unsigned char buf[4];
+
+ double target_f_osc = target_freq + first_IF;
+
+ double f_ref = 4e6 / d_reference_divider;
+
+ // f_osc = f_ref * 8 * divisor
+ // divisor = f_osc / (f_ref * 8)
+
+ int divisor = (int) ((target_f_osc + (f_ref * 4)) / (f_ref * 8));
+ double actual_freq = (f_ref * 8 * divisor) - first_IF;
+ if (p_actual_freq != 0)
+ *p_actual_freq = actual_freq;
+
+ if ((divisor & ~0x7fff) != 0) // 15 bit divisor
+ return false;
+
+ buf[0] = (divisor >> 8) & 0xff; // DB1
+ buf[1] = divisor & 0xff; // DB2
+ buf[2] = control_byte_1 (d_fast_tuning_p, d_reference_divider);
+ buf[3] = control_byte_2 (target_freq, true);
+
+#if 0
+ printf ("set_RF_freq: target: %g MHz actual: %g MHz %02x %02x %02x %02x\n",
+ target_freq/1e6, actual_freq/1e6, buf[0], buf[1], buf[2], buf[3]);
+#endif
+
+ return d_i2c->write (d_i2c_addr, buf, 4);
+}
+
+/*!
+ * \returns true iff PLL is locked
+ */
+bool
+microtune_4937::pll_locked_p ()
+{
+ // FIXME
+ return true;
+}
+
+/*!
+ * \returns the output frequency of the tuner in Hz.
+ */
+double
+microtune_4937::get_output_freq ()
+{
+ return 5.75e6; // 3x7702
+}
diff --git a/gnuradio-core/src/lib/io/microtune_4937.h b/gnuradio-core/src/lib/io/microtune_4937.h
new file mode 100644
index 0000000000..84c8d6112c
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4937.h
@@ -0,0 +1,66 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_MICROTUNE_4937_H
+#define INCLUDED_MICROTUNE_4937_H
+
+#include <microtune_xxxx.h>
+
+/*!
+ * \brief class for controlling microtune 4937 tuner module
+ */
+class microtune_4937 : public microtune_xxxx {
+public:
+ microtune_4937 (i2c_sptr i2c, int i2c_addr = 0x61);
+ virtual ~microtune_4937 ();
+
+ /*!
+ * \brief select RF frequency to be tuned to output frequency.
+ * \p freq is the requested frequency in Hz, \p actual_freq
+ * is set to the actual frequency tuned. It takes about 100 ms
+ * for the PLL to settle.
+ *
+ * \returns true iff sucessful.
+ */
+ bool set_RF_freq (double freq, double *actual_freq);
+
+ /*!
+ * \returns true iff PLL is locked
+ */
+ bool pll_locked_p ();
+
+ /*!
+ * \returns the output frequency (IF center freq) of the tuner in Hz.
+ */
+ double get_output_freq ();
+
+ private:
+
+ i2c_sptr d_i2c;
+ int d_i2c_addr;
+ int d_reference_divider;
+ bool d_fast_tuning_p; /* if set, higher charge pump current:
+ faster tuning, worse phase noise
+ for distance < 10kHz to the carrier */
+};
+
+#endif /* INCLUDED_MICROTUNE_4937_H */
diff --git a/gnuradio-core/src/lib/io/microtune_4937_eval_board.cc b/gnuradio-core/src/lib/io/microtune_4937_eval_board.cc
new file mode 100644
index 0000000000..82a03740c4
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "microtune_4937_eval_board.h"
+#include "microtune_eval_board_defs.h"
+#include "ppio.h"
+#include "microtune_4937.h"
+
+static const int TUNER_I2C_ADDR = 0x61;
+
+microtune_4937_eval_board::microtune_4937_eval_board (int which_pp)
+ : microtune_xxxx_eval_board (which_pp)
+{
+ d_tuner = new microtune_4937 (d_i2c, TUNER_I2C_ADDR);
+
+ // disable upstream amplifier
+ d_ppio->lock ();
+ int t = d_ppio->read_data ();
+ t &= ~(UT_DP_TX_ENABLE | UT_DP_TX_SDA | UT_DP_TX_SCL);
+ t |= UT_DP_TX_AS;
+ d_ppio->write_data (t);
+ d_ppio->unlock ();
+}
+
+microtune_4937_eval_board::~microtune_4937_eval_board ()
+{
+ // Default action is OK
+}
+
+
+static const float RF_MIN_V = 1.5; // RF AGC control voltages
+static const float RF_MAX_V = 4.0;
+static const float IF_MIN_V = 2.0; // IF AGC control voltages
+static const float IF_MAX_V = 4.0;
+
+static const float MIN_AGC = 0; // bottom of synthetic range
+static const float MAX_AGC = 1000; // top of synthetic range
+
+static const float CUTOVER_POINT = 667;
+
+
+// linear is in the range MIN_AGC to MAX_AGC
+
+static float
+linear_to_RF_AGC_voltage (float linear)
+{
+ if (linear >= CUTOVER_POINT)
+ return RF_MAX_V;
+
+ float slope = (RF_MAX_V - RF_MIN_V) / CUTOVER_POINT;
+ return RF_MIN_V + linear * slope;
+}
+
+static float
+linear_to_IF_AGC_voltage (float linear)
+{
+ if (linear < CUTOVER_POINT)
+ return IF_MIN_V;
+
+ float slope = (IF_MAX_V - IF_MIN_V) / (MAX_AGC - CUTOVER_POINT);
+ return IF_MIN_V + (linear - CUTOVER_POINT) * slope;
+}
+
+void
+microtune_4937_eval_board::set_AGC (float v)
+{
+ if (v < MIN_AGC)
+ v = MIN_AGC;
+
+ if (v > MAX_AGC)
+ v = MAX_AGC;
+
+ float rf_agc_voltage = linear_to_RF_AGC_voltage (v);
+ float if_agc_voltage = linear_to_IF_AGC_voltage (v);
+
+ set_RF_AGC_voltage (rf_agc_voltage);
+ set_IF_AGC_voltage (if_agc_voltage);
+}
diff --git a/gnuradio-core/src/lib/io/microtune_4937_eval_board.h b/gnuradio-core/src/lib/io/microtune_4937_eval_board.h
new file mode 100644
index 0000000000..8a8f46b062
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4937_eval_board.h
@@ -0,0 +1,48 @@
+/* -*- C++ -*- */
+/*
+ * Copyright 2001,2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_MICROTUNE_4937_EVAL_BOARD_H
+#define INCLUDED_MICROTUNE_4937_EVAL_BOARD_H
+
+#include "microtune_xxxx_eval_board.h"
+
+/*!
+ * \brief control microtune 4937 eval board
+ */
+
+class microtune_4937_eval_board : public microtune_xxxx_eval_board {
+public:
+ microtune_4937_eval_board (int which_pp = 0);
+ ~microtune_4937_eval_board ();
+
+ /*!
+ * \brief set RF and IF AGC levels together (scale [0, 1000])
+ *
+ * This provides a simple linear interface for adjusting both
+ * the RF and IF gain in consort. This is the easy to use interface.
+ * 0 corresponds to minimum gain. 1000 corresponds to maximum gain.
+ */
+ virtual void set_AGC (float value_0_1000);
+};
+
+
+#endif /* INCLUDED_MICROTUNE_4937_EVAL_BOARD_H */
diff --git a/gnuradio-core/src/lib/io/microtune_4937_eval_board.i b/gnuradio-core/src/lib/io/microtune_4937_eval_board.i
new file mode 100644
index 0000000000..106832e3d5
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+class microtune_4937_eval_board : public microtune_xxxx_eval_board {
+public:
+ microtune_4937_eval_board (int which_pp = 0);
+ ~microtune_4937_eval_board ();
+
+ /*!
+ * \brief set RF and IF AGC levels together (scale [0, 1000])
+ *
+ * This provides a simple linear interface for adjusting both
+ * the RF and IF gain in consort. This is the easy to use interface.
+ * 0 corresponds to minimum gain. 1000 corresponds to maximum gain.
+ */
+ virtual void set_AGC (float value_0_1000);
+};
diff --git a/gnuradio-core/src/lib/io/microtune_eval_board.i b/gnuradio-core/src/lib/io/microtune_eval_board.i
new file mode 100644
index 0000000000..7c673e3a5b
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * SWIG interface defs for Microtune 4937 and eval board with Eric's daughterboard
+ */
+
+/*!
+ * \brief abstract class for controlling microtune 4937 tuner module
+ */
+class microtune_4937 {
+public:
+ microtune_4937 ();
+
+ virtual ~microtune_4937 ();
+
+ // returns actual freq or 0 if error (easier interface for SWIG)
+ double set_RF_freq (double freq);
+
+ /*!
+ * \returns true iff PLL is locked
+ */
+ bool pll_locked_p ();
+
+ /*!
+ * \returns the output frequency (IF center freq) of the tuner in Hz.
+ */
+ double get_output_freq ();
+
+
+ private:
+ //! \returns true iff successful
+ virtual bool i2c_write (int addr, const unsigned char *buf, int nbytes) = 0;
+
+ //! \returns number of bytes read or -1 if error
+ virtual int i2c_read (int addr, unsigned char *buf, int max_bytes) = 0;
+
+ int d_reference_divider;
+ bool d_fast_tuning_p; /* if set, higher charge pump current:
+ faster tuning, worse phase noise
+ for distance < 10kHz to the carrier */
+};
+
+/*!
+ * \brief concrete class for controlling microtune 4937 eval board attached to parallel port
+ */
+class microtune_eval_board : public microtune_4937 {
+public:
+ microtune_eval_board (int which_pp = 0);
+ ~microtune_eval_board ();
+
+ //! is the eval board present?
+ bool board_present_p ();
+
+ /*!
+ * \brief set RF and IF AGC control voltages ([0, 5] volts)
+ */
+ void set_RF_AGC_voltage (float volts);
+ void set_IF_AGC_voltage (float volts);
+
+ /*!
+ * \brief set RF and IF AGC levels together (scale [0, 1000])
+ *
+ * This provides a simple linear interface for adjusting both
+ * the RF and IF gain in consort. This is the easy to use interface.
+ * 0 corresponds to minimum gain. 1000 corresponds to maximum gain.
+ */
+ void set_AGC (float value_0_1000);
+
+private:
+ //! \returns true iff successful
+ virtual bool i2c_write (int addr, const unsigned char *buf, int nbytes);
+
+ //! \returns number of bytes read or -1 if error
+ virtual int i2c_read (int addr, unsigned char *buf, int max_bytes);
+};
diff --git a/gnuradio-core/src/lib/io/microtune_eval_board_defs.h b/gnuradio-core/src/lib/io/microtune_eval_board_defs.h
new file mode 100644
index 0000000000..5245fd5ceb
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _MICROTUNE_EVAL_BOARD_DEFS_H_
+#define _MICROTUNE_EVAL_BOARD_DEFS_H_
+
+/*
+ * The Microtune 4937DI5 cable modem tuner eval board is controlled
+ * by bit banging the PC parallel port. This file defines the relevant
+ * bits.
+ *
+ * The parallel port has an 8 bit data port (output),
+ * an 8 bit control port (output) and
+ * an 8 bit status port (input).
+ *
+ * Not all bits of the control and status ports may be arbitrarily used.
+ */
+
+
+// parallel port data port constants (output)
+
+static const int UT_DP_TX_SDA = 0x01; // upstream control bus
+static const int UT_DP_TX_SCL = 0x02; // upstream control bus
+static const int UT_DP_TX_AS = 0x04; // upstream control bus
+static const int UT_DP_TX_ENABLE = 0x08; // upstream h/w enable
+// bits 4,5,6 not used
+static const int UT_DP_TUNER_SDA_OUT = 0x80; // tuner i2c bus data
+
+// parallel port control port constants (output)
+
+static const int UT_CP_TUNER_SCL = 0x08; // tuner i2c bus clock
+static const int UT_CP_MUST_BE_ZERO = 0xf0; // must be zero
+
+// parallel port status port constants (input)
+
+// bits 0,1,2 not used
+static const int UT_SP_TUNER_SCL_LOOP_BACK= 0x08; // inverted SCL loop back
+static const int UT_SP_SHOULD_BE_ZERO = 0x10; // reads as zero
+static const int UT_SP_SHOULD_BE_ONE = 0x20; // reads as one
+// bit 6 not used
+static const int UT_SP_TUNER_SDA_IN = 0x80;
+
+
+#endif /* _MICROTUNE_EVAL_BOARD_DEFS_H_ */
diff --git a/gnuradio-core/src/lib/io/microtune_xxxx.cc b/gnuradio-core/src/lib/io/microtune_xxxx.cc
new file mode 100644
index 0000000000..8633b111b2
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "microtune_xxxx.h"
+
+microtune_xxxx::~microtune_xxxx ()
+{
+ // nop
+}
+
+double
+microtune_xxxx::set_RF_freq (double target_freq)
+{
+ double actual_freq = 0.0;
+
+ if (set_RF_freq (target_freq, &actual_freq))
+ return actual_freq;
+
+ return 0.0;
+}
+
+
diff --git a/gnuradio-core/src/lib/io/microtune_xxxx.h b/gnuradio-core/src/lib/io/microtune_xxxx.h
new file mode 100644
index 0000000000..8fac06d8f8
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_xxxx.h
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2003,2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_MICROTUNE_XXXX_H
+#define INCLUDED_MICROTUNE_XXXX_H
+
+#include <boost/shared_ptr.hpp>
+
+class i2c;
+typedef boost::shared_ptr<i2c> i2c_sptr;
+
+/*!
+ * \brief abstract class for controlling microtune {4937,4702} tuner modules
+ */
+class microtune_xxxx {
+public:
+ microtune_xxxx () {}
+ virtual ~microtune_xxxx ();
+
+ /*!
+ * \brief select RF frequency to be tuned to output frequency.
+ * \p freq is the requested frequency in Hz, \p actual_freq
+ * is set to the actual frequency tuned. It takes about 100 ms
+ * for the PLL to settle.
+ *
+ * \returns true iff sucessful.
+ */
+ virtual bool set_RF_freq (double freq, double *actual_freq) = 0;
+
+ // returns actual freq or 0 if error (easier interface for SWIG)
+ double set_RF_freq (double freq);
+
+ /*!
+ * \returns true iff PLL is locked
+ */
+ virtual bool pll_locked_p () = 0;
+
+ /*!
+ * \returns the output frequency (IF center freq) of the tuner in Hz.
+ */
+ virtual double get_output_freq () = 0;
+
+};
+
+#endif /* INCLUDED_MICROTUNE_XXXX_H */
diff --git a/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.cc b/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.cc
new file mode 100644
index 0000000000..a7ea98d6f1
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.cc
@@ -0,0 +1,140 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "microtune_xxxx_eval_board.h"
+#include "microtune_eval_board_defs.h"
+#include "microtune_xxxx.h"
+#include "ppio.h"
+#include "i2c_bitbang.h"
+#include "i2c_bbio_pp.h"
+#include <cmath>
+
+static int AGC_DAC_I2C_ADDR = 0x2C;
+
+microtune_xxxx_eval_board::microtune_xxxx_eval_board (int which_pp)
+{
+ d_ppio = make_ppio (which_pp);
+ d_i2c = make_i2c_bitbang (make_i2c_bbio_pp (d_ppio));
+ d_tuner = 0;
+}
+
+microtune_xxxx_eval_board::~microtune_xxxx_eval_board ()
+{
+ delete d_tuner;
+ d_tuner = 0;
+}
+
+
+//! is the eval board present?
+bool
+microtune_xxxx_eval_board::board_present_p ()
+{
+ bool result = true;
+ d_ppio->lock ();
+
+ int t = d_ppio->read_status ();
+ if ((t & UT_SP_SHOULD_BE_ZERO) != 0
+ || (t & UT_SP_SHOULD_BE_ONE) != UT_SP_SHOULD_BE_ONE)
+ result = false;
+
+ // could also see if SCL is looped back or not, but that seems like overkill
+
+ d_ppio->unlock ();
+ return result;
+}
+
+/*
+ * ----------------------------------------------------------------
+ * AGC stuff
+ *
+ * We're using a MAX518 8-bit 5V dual dac for setting the AGC's
+ * ----------------------------------------------------------------
+ */
+void
+microtune_xxxx_eval_board::write_dac (int which, int value)
+{
+ unsigned char cmd[2];
+ cmd[0] = which & 1;
+ cmd[1] = value;
+ d_i2c->write (AGC_DAC_I2C_ADDR, cmd, sizeof (cmd));
+}
+
+void
+microtune_xxxx_eval_board::write_both_dacs (int value0, int value1)
+{
+ unsigned char cmd[4];
+ cmd[0] = 0;
+ cmd[1] = value0;
+ cmd[2] = 1;
+ cmd[3] = value1;
+ d_i2c->write (AGC_DAC_I2C_ADDR, cmd, sizeof (cmd));
+}
+
+static int scale_volts (float volts)
+{
+ int n;
+ n = (int) rint (volts * (256 / 5.0));
+ if (n < 0)
+ n = 0;
+ if (n > 255)
+ n = 255;
+
+ return n;
+}
+
+void
+microtune_xxxx_eval_board::set_RF_AGC_voltage (float volts)
+{
+ write_dac (0, scale_volts (volts));
+}
+
+void
+microtune_xxxx_eval_board::set_IF_AGC_voltage (float volts)
+{
+ write_dac (1, scale_volts (volts));
+}
+
+// delegate to tuner
+
+bool
+microtune_xxxx_eval_board::set_RF_freq (double freq, double *actual_freq)
+{
+ return d_tuner->set_RF_freq (freq, actual_freq);
+}
+
+double
+microtune_xxxx_eval_board::set_RF_freq (double freq)
+{
+ return d_tuner->set_RF_freq (freq);
+}
+
+bool
+microtune_xxxx_eval_board::pll_locked_p ()
+{
+ return d_tuner->pll_locked_p ();
+}
+
+double
+microtune_xxxx_eval_board::get_output_freq ()
+{
+ return d_tuner->get_output_freq ();
+}
diff --git a/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.h b/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.h
new file mode 100644
index 0000000000..3a817b6985
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.h
@@ -0,0 +1,96 @@
+/* -*- C++ -*- */
+/*
+ * Copyright 2001,2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_MICROTUNE_XXXX_EVAL_BOARD_H
+#define INCLUDED_MICROTUNE_XXXX_EVAL_BOARD_H
+
+#include <boost/shared_ptr.hpp>
+
+class microtune_xxxx;
+
+class ppio;
+typedef boost::shared_ptr<ppio> ppio_sptr;
+
+class i2c;
+typedef boost::shared_ptr<i2c> i2c_sptr;
+
+/*!
+ * \brief abstract class for controlling microtune xxxx eval board
+ */
+class microtune_xxxx_eval_board {
+public:
+ microtune_xxxx_eval_board (int which_pp = 0);
+ virtual ~microtune_xxxx_eval_board ();
+
+ //! is the eval board present?
+ bool board_present_p ();
+
+ /*!
+ * \brief set RF and IF AGC control voltages ([0, 5] volts)
+ */
+ void set_RF_AGC_voltage (float volts);
+ void set_IF_AGC_voltage (float volts);
+
+ /*!
+ * \brief set RF and IF AGC levels together (scale [0, 1000])
+ *
+ * This provides a simple linear interface for adjusting both
+ * the RF and IF gain in consort. This is the easy to use interface.
+ * 0 corresponds to minimum gain. 1000 corresponds to maximum gain.
+ */
+ virtual void set_AGC (float value_0_1000) = 0;
+
+ /*!
+ * \brief select RF frequency to be tuned to output frequency.
+ * \p freq is the requested frequency in Hz, \p actual_freq
+ * is set to the actual frequency tuned. It takes about 100 ms
+ * for the PLL to settle.
+ *
+ * \returns true iff sucessful.
+ */
+ bool set_RF_freq (double freq, double *actual_freq);
+
+ // returns actual freq or 0 if error (easier interface for SWIG)
+ double set_RF_freq (double freq);
+
+ /*!
+ * \returns true iff PLL is locked
+ */
+ bool pll_locked_p ();
+
+ /*!
+ * \returns the output frequency (IF center freq) of the tuner in Hz.
+ */
+ double get_output_freq ();
+
+
+private:
+ void write_dac (int which, int value);
+ void write_both_dacs (int val0, int val1);
+
+protected:
+ ppio_sptr d_ppio;
+ i2c_sptr d_i2c;
+ microtune_xxxx *d_tuner;
+};
+
+#endif /* INCLUDED_MICROTUNE_XXXX_EVAL_BOARD_H */
diff --git a/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.i b/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.i
new file mode 100644
index 0000000000..2e43f27aad
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+class microtune_xxxx_eval_board {
+public:
+ microtune_xxxx_eval_board (int which_pp = 0);
+ virtual ~microtune_xxxx_eval_board ();
+
+ //! is the eval board present?
+ bool board_present_p ();
+
+ /*!
+ * \brief set RF and IF AGC control voltages ([0, 5] volts)
+ */
+ void set_RF_AGC_voltage (float volts);
+ void set_IF_AGC_voltage (float volts);
+
+ /*!
+ * \brief set RF and IF AGC levels together (scale [0, 1000])
+ *
+ * This provides a simple linear interface for adjusting both
+ * the RF and IF gain in consort. This is the easy to use interface.
+ * 0 corresponds to minimum gain. 1000 corresponds to maximum gain.
+ */
+ virtual void set_AGC (float value_0_1000) = 0;
+
+ // returns actual freq or 0 if error (easier interface for SWIG)
+ double set_RF_freq (double freq);
+
+ /*!
+ * \returns true iff PLL is locked
+ */
+ bool pll_locked_p ();
+
+ /*!
+ * \returns the output frequency (IF center freq) of the tuner in Hz.
+ */
+ double get_output_freq ();
+};
diff --git a/gnuradio-core/src/lib/io/ppio.cc b/gnuradio-core/src/lib/io/ppio.cc
new file mode 100644
index 0000000000..86f402bbf7
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <ppio.h>
+#include <ppio_ppdev.h>
+
+ppio::~ppio ()
+{
+}
+
+// Factory method.
+//
+// Right now, we've only got one subclass we like. If there were more,
+// we'd instantiate the "right one" here.
+
+ppio_sptr
+make_ppio (int which_pp)
+{
+ return make_ppio_ppdev (which_pp);
+}
diff --git a/gnuradio-core/src/lib/io/ppio.h b/gnuradio-core/src/lib/io/ppio.h
new file mode 100644
index 0000000000..4181387057
--- /dev/null
+++ b/gnuradio-core/src/lib/io/ppio.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_PPIO_H
+#define INCLUDED_PPIO_H
+
+#include <boost/shared_ptr.hpp>
+
+class ppio;
+typedef boost::shared_ptr<ppio> ppio_sptr;
+
+
+/*!
+ * \brief abstract class that provides low level access to parallel port bits
+ */
+
+class ppio {
+ public:
+ ppio () {}
+ virtual ~ppio ();
+
+ virtual void write_data (unsigned char v) = 0;
+ virtual unsigned char read_data () = 0;
+ virtual void write_control (unsigned char v) = 0;
+ virtual unsigned char read_control () = 0;
+ virtual unsigned char read_status () = 0;
+
+ virtual void lock () = 0;
+ virtual void unlock () = 0;
+};
+
+/*!
+ * \brief Factory method.
+ *
+ * Split out from class to make life easier for SWIG
+ */
+
+ppio_sptr make_ppio (int which_pp);
+
+
+#endif /* INCLUDED_PPIO_H */
+
diff --git a/gnuradio-core/src/lib/io/ppio.i b/gnuradio-core/src/lib/io/ppio.i
new file mode 100644
index 0000000000..2eaddc204b
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+class ppio;
+typedef boost::shared_ptr<ppio> ppio_sptr;
+
+%template(ppio_sptr) boost::shared_ptr<ppio>;
+
+/*!
+ * \brief abstract class that provides low level access to parallel port bits
+ */
+
+class ppio {
+ public:
+ ppio () {}
+ virtual ~ppio ();
+
+ virtual void write_data (unsigned char v) = 0;
+ virtual unsigned char read_data () = 0;
+ virtual void write_control (unsigned char v) = 0;
+ virtual unsigned char read_control () = 0;
+ virtual unsigned char read_status () = 0;
+
+ virtual void lock () = 0;
+ virtual void unlock () = 0;
+};
+
+
+ppio_sptr make_ppio (int which_pp);
diff --git a/gnuradio-core/src/lib/io/ppio_ppdev.cc b/gnuradio-core/src/lib/io/ppio_ppdev.cc
new file mode 100644
index 0000000000..bfdaa3de09
--- /dev/null
+++ b/gnuradio-core/src/lib/io/ppio_ppdev.cc
@@ -0,0 +1,221 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2003,2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <ppio_ppdev.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <iostream>
+#include <errno.h>
+#include <stdio.h>
+#include <stdexcept>
+#ifdef HAVE_LINUX_PPDEV_H
+#include <sys/ioctl.h>
+#include <linux/ppdev.h>
+#include <linux/parport.h>
+#include <sstream>
+#else
+// #warn "ppio_ppdev is not functional on this platform"
+#endif
+
+// These control port bits are active low.
+// We toggle them so that this weirdness doesn't get get propagated
+// through our interface.
+
+static int CP_ACTIVE_LOW_BITS = 0x0B;
+
+// These status port bits are active low.
+// We toggle them so that this weirdness doesn't get get propagated
+// through our interface.
+
+static int SP_ACTIVE_LOW_BITS = 0x80;
+
+#ifndef HAVE_LINUX_PPDEV_H // use stubs
+
+ppio_ppdev::ppio_ppdev (int which)
+{
+ std::cerr << "ppio_ppdev: Not implemented on this platform\n";
+ throw std::runtime_error ("not implmeneted");
+}
+
+ppio_ppdev::~ppio_ppdev ()
+{
+}
+
+void
+ppio_ppdev::write_data (unsigned char v)
+{
+}
+
+unsigned char
+ppio_ppdev::read_data ()
+{
+ return 0;
+}
+
+void
+ppio_ppdev::write_control (unsigned char v)
+{
+}
+
+unsigned char
+ppio_ppdev::read_control ()
+{
+ return 0;
+}
+
+unsigned char
+ppio_ppdev::read_status ()
+{
+ return 0;
+}
+
+void
+ppio_ppdev::lock ()
+{
+}
+
+void
+ppio_ppdev::unlock ()
+{
+}
+
+#else
+
+// The real code...
+
+ppio_ppdev::ppio_ppdev (int which)
+{
+ std::ostringstream filename;
+ filename << "/dev/parport" << which;
+ const char *c_filename = filename.str().c_str();
+
+ if ((d_fd = open (c_filename, O_RDWR)) < 0){
+ int my_errno = errno;
+ perror (c_filename);
+ if (my_errno == ENOENT){
+ std::cerr << "Does the device file " << c_filename << " exist?\n";
+ std::cerr << "If not, as root execute: \n";
+ std::cerr << " # mknod " << c_filename << " c 99 0\n";
+ std::cerr << " # chmod 666 " << c_filename << std::endl;
+ }
+ throw std::runtime_error ("open");
+ }
+
+ int mode = IEEE1284_MODE_COMPAT;
+ if (ioctl (d_fd, PPSETMODE, &mode) != 0){
+ perror ("ppio_ppdev: PPSETMODE");
+ close (d_fd);
+ throw std::runtime_error ("PPSETMODE");
+ }
+}
+
+ppio_ppdev::~ppio_ppdev ()
+{
+ close (d_fd);
+}
+
+
+void
+ppio_ppdev::write_data (unsigned char v)
+{
+ if (ioctl (d_fd, PPWDATA, &v) != 0){
+ perror ("ppio_ppdev: PPWDATA");
+ throw std::runtime_error ("PPWDATA");
+ }
+}
+
+unsigned char
+ppio_ppdev::read_data ()
+{
+ unsigned char v;
+
+ if (ioctl (d_fd, PPRDATA, &v) != 0){
+ perror ("ppio_ppdev: PPRDATA");
+ throw std::runtime_error ("PPRDATA");
+ }
+ return v;
+}
+
+void
+ppio_ppdev::write_control (unsigned char v)
+{
+ unsigned char ctrl = v ^ CP_ACTIVE_LOW_BITS;
+ if (ioctl (d_fd, PPWCONTROL, &ctrl) != 0){
+ perror ("ppio_ppdev: PPWCONTROL");
+ throw std::runtime_error ("PPWCONTROL");
+ }
+}
+
+unsigned char
+ppio_ppdev::read_control ()
+{
+ unsigned char ctrl;
+ if (ioctl (d_fd, PPRCONTROL, &ctrl) != 0){
+ perror ("ppio_ppdev: PPRCONTROL");
+ throw std::runtime_error ("PPRCONTROL");
+ }
+
+ return ctrl ^ CP_ACTIVE_LOW_BITS;
+}
+
+unsigned char
+ppio_ppdev::read_status ()
+{
+ unsigned char status;
+ if (ioctl (d_fd, PPRSTATUS, &status) != 0){
+ perror ("ppio_ppdev: PPRSTATUS");
+ throw std::runtime_error ("PPRSTATUS");
+ }
+
+ return status ^ SP_ACTIVE_LOW_BITS;
+}
+
+void
+ppio_ppdev::lock ()
+{
+ if (ioctl (d_fd, PPCLAIM) != 0){
+ perror ("ppio_ppdev: PPCLAIM");
+ throw std::runtime_error ("PPCLAIM");
+ }
+}
+
+void
+ppio_ppdev::unlock ()
+{
+ if (ioctl (d_fd, PPRELEASE) != 0){
+ perror ("ppio_ppdev: PPRELEASE");
+ throw std::runtime_error ("PPRELEASE");
+ }
+}
+
+#endif
+
+ppio_ppdev_sptr
+make_ppio_ppdev (int which)
+{
+ return ppio_ppdev_sptr (new ppio_ppdev (which));
+}
diff --git a/gnuradio-core/src/lib/io/ppio_ppdev.h b/gnuradio-core/src/lib/io/ppio_ppdev.h
new file mode 100644
index 0000000000..8ac4a35de4
--- /dev/null
+++ b/gnuradio-core/src/lib/io/ppio_ppdev.h
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_PPIO_PPDEV_H
+#define INCLUDED_PPIO_PPDEV_H
+
+#include <ppio.h>
+
+class ppio_ppdev;
+typedef boost::shared_ptr<ppio_ppdev> ppio_ppdev_sptr;
+
+/*!
+ * \brief access to parallel port bits using the linux ppdev interface
+ */
+
+class ppio_ppdev : public ppio {
+ friend ppio_ppdev_sptr make_ppio_ppdev (int which = 0);
+ ppio_ppdev (int which = 0);
+
+ public:
+ virtual ~ppio_ppdev ();
+
+ virtual void write_data (unsigned char v);
+ virtual unsigned char read_data ();
+ virtual void write_control (unsigned char v);
+ virtual unsigned char read_control ();
+ virtual unsigned char read_status ();
+
+ virtual void lock ();
+ virtual void unlock ();
+
+ private:
+ int d_fd;
+};
+
+ppio_ppdev_sptr
+make_ppio_ppdev (int which);
+
+
+#endif /* INCLUDED_PPIO_PPDEV_H */
+
diff --git a/gnuradio-core/src/lib/io/sdr_1000.cc b/gnuradio-core/src/lib/io/sdr_1000.cc
new file mode 100644
index 0000000000..1cb9b9afb9
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <sdr_1000.h>
+#include <ppio.h>
+
+sdr_1000_base::sdr_1000_base (int which_pp)
+{
+ d_ppio = make_ppio (which_pp);
+ d_shadow[0] = 0;
+ d_shadow[1] = 0;
+ d_shadow[2] = 0;
+ d_shadow[3] = 0;
+ reset ();
+}
+
+sdr_1000_base::~sdr_1000_base ()
+{
+}
+
+void
+sdr_1000_base::reset ()
+{
+ d_ppio->lock ();
+ d_ppio->write_control (0x0F);
+ d_ppio->unlock ();
+ write_latch (L_EXT, 0x00, 0xff);
+ write_latch (L_BAND, 0x00, 0xff);
+ write_latch (L_DDS0, 0x80, 0xff); // hold DDS in reset
+ write_latch (L_DDS1, 0x00, 0xff);
+}
+
+
+void
+sdr_1000_base::write_latch (int which, int value, int mask)
+{
+ if (!(0 <= which && which <= 3))
+ return;
+
+ d_ppio->lock ();
+ d_shadow[which] = (d_shadow[which] & ~mask) | (value & mask);
+ d_ppio->write_data (d_shadow[which]);
+ d_ppio->write_control (0x0F ^ (1 << which));
+ d_ppio->write_control (0x0F);
+ d_ppio->unlock ();
+}
diff --git a/gnuradio-core/src/lib/io/sdr_1000.h b/gnuradio-core/src/lib/io/sdr_1000.h
new file mode 100644
index 0000000000..f9ddb35ccf
--- /dev/null
+++ b/gnuradio-core/src/lib/io/sdr_1000.h
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_SDR_1000_H
+#define INCLUDED_SDR_1000_H
+
+#include <boost/shared_ptr.hpp>
+
+class ppio;
+typedef boost::shared_ptr<ppio> ppio_sptr;
+
+
+enum { L_EXT = 0, L_BAND = 1, L_DDS0 = 2, L_DDS1 = 3 };
+
+/*!
+ * \brief Very low level interface to SDR 1000 xcvr hardware
+ * \sa sdr_1000.py for a higher level interface.
+ */
+class sdr_1000_base {
+ ppio_sptr d_ppio;
+ int d_shadow[4]; // shadow latches
+
+public:
+
+ sdr_1000_base (int which_pp);
+ ~sdr_1000_base ();
+
+ void reset ();
+ void write_latch (int which, int value, int mask);
+};
+
+#endif /* INCLUDED_SDR_1000_H */
diff --git a/gnuradio-core/src/lib/io/sdr_1000.i b/gnuradio-core/src/lib/io/sdr_1000.i
new file mode 100644
index 0000000000..46690e0ce2
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+const int L_EXT = 0;
+const int L_BAND = 1;
+const int L_DDS0 = 2;
+const int L_DDS1 = 3;
+
+class sdr_1000_base {
+public:
+
+ sdr_1000_base (int which_pp);
+ ~sdr_1000_base ();
+
+ void reset ();
+ void write_latch (int which, int value, int mask);
+};
diff --git a/gnuradio-core/src/lib/missing/Makefile.am b/gnuradio-core/src/lib/missing/Makefile.am
new file mode 100644
index 0000000000..7985fb3e11
--- /dev/null
+++ b/gnuradio-core/src/lib/missing/Makefile.am
@@ -0,0 +1,33 @@
+#
+# Copyright 2003,2004 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = \
+ getopt.h \
+ getopt.c \
+ gettimeofday.c \
+ usleep.c
+
+noinst_LTLIBRARIES = libmissing.la
+
+libmissing_la_SOURCES = \
+ bug_work_around_8.cc
diff --git a/gnuradio-core/src/lib/missing/bug_work_around_8.cc b/gnuradio-core/src/lib/missing/bug_work_around_8.cc
new file mode 100644
index 0000000000..b79702275c
--- /dev/null
+++ b/gnuradio-core/src/lib/missing/bug_work_around_8.cc
@@ -0,0 +1,2 @@
+// if libmisc has no sources, it doesn't get built correctly
+static int gr_bug_work_around_8;
diff --git a/gnuradio-core/src/lib/missing/getopt.c b/gnuradio-core/src/lib/missing/getopt.c
new file mode 100644
index 0000000000..93fb6ea5b1
--- /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 2, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* 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 0000000000..45541f5ac0
--- /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 2, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef _GETOPT_H
+#define _GETOPT_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns EOF, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+ for unrecognized options. */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized. */
+
+extern int optopt;
+
+/* Describe the long-named options requested by the application.
+ The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+ of `struct option' terminated by an element containing a name which is
+ zero.
+
+ The field `has_arg' is:
+ no_argument (or 0) if the option does not take an argument,
+ required_argument (or 1) if the option requires an argument,
+ optional_argument (or 2) if the option takes an optional argument.
+
+ If the field `flag' is not NULL, it points to a variable that is set
+ to the value given in the field `val' when the option is found, but
+ left unchanged if the option is not found.
+
+ To have a long-named option do something other than set an `int' to
+ a compiled-in constant, such as set a value from `optarg', set the
+ option's `flag' field to zero and its `val' field to a nonzero
+ value (the equivalent single-letter option character, if there is
+ one). For long options that have a zero `flag' field, `getopt'
+ returns the contents of the `val' field. */
+
+struct option
+{
+#if __STDC__
+ const char *name;
+#else
+ char *name;
+#endif
+ /* has_arg can't be an enum because some compilers complain about
+ type mismatches in all the code that assumes it is an int. */
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'. */
+
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+#if __STDC__
+#if defined(__GNU_LIBRARY__)
+/* Many other libraries have conflicting prototypes for getopt, with
+ differences in the consts, in stdlib.h. To avoid compilation
+ errors, only prototype getopt for the GNU C library. */
+extern int getopt (int argc, char *const *argv, const char *shortopts);
+#else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+#endif /* not __GNU_LIBRARY__ */
+extern int getopt_long (int argc, char *const *argv, const char *shortopts,
+ const struct option *longopts, int *longind);
+extern int getopt_long_only (int argc, char *const *argv,
+ const char *shortopts,
+ const struct option *longopts, int *longind);
+
+/* Internal only. Users should not call this directly. */
+extern int _getopt_internal (int argc, char *const *argv,
+ const char *shortopts,
+ const struct option *longopts, int *longind,
+ int long_only);
+#else /* not __STDC__ */
+extern int getopt ();
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+#endif /* not __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GETOPT_H */
diff --git a/gnuradio-core/src/lib/missing/gettimeofday.c b/gnuradio-core/src/lib/missing/gettimeofday.c
new file mode 100644
index 0000000000..4ed15e21f8
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+#ifdef HAVE_WINBASE_H
+# include <winbase.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+/*
+ * broken implementation for WIN32.
+ * FIXME: usec precision
+ */
+int gettimeofday(struct timeval *tv, struct timezone *tz)
+{
+ if (tv) {
+ time_t tm;
+
+ time(&tm);
+ tv->tv_sec = tm;
+ tv->tv_usec = 0;
+ }
+ return 0;
+}
+
diff --git a/gnuradio-core/src/lib/missing/usleep.c b/gnuradio-core/src/lib/missing/usleep.c
new file mode 100644
index 0000000000..4a0f75ea8f
--- /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 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+#include <config.h>
+
+#ifndef HAVE_USLEEP
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+#endif
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+#ifdef HAVE_WINBASE_H
+# include <winbase.h>
+#endif
+
+#ifdef apollo
+# include <apollo/base.h>
+# include <apollo/time.h>
+ static time_$clock_t DomainTime100mS =
+ {
+ 0, 100000/4
+ };
+ static status_$t DomainStatus;
+#endif
+
+/* Sleep USECONDS microseconds, or until a previously set timer goes off. */
+int
+usleep (unsigned long useconds)
+{
+#ifdef apollo
+ /* The usleep function does not work under the SYS5.3 environment.
+ Use the Domain/OS time_$wait call instead. */
+ time_$wait (time_$relative, DomainTime100mS, &DomainStatus);
+#elif defined(HAVE_SSLEEP) /* Win32 */
+ Sleep( useconds/1000 );
+#else
+ struct timeval delay;
+
+ delay.tv_sec = 0;
+ delay.tv_usec = useconds;
+ select (0, 0, 0, 0, &delay);
+#endif
+ return 0;
+}
+
+#endif /* !HAVE_USLEEP */
diff --git a/gnuradio-core/src/lib/omnithread/Makefile.am b/gnuradio-core/src/lib/omnithread/Makefile.am
new file mode 100644
index 0000000000..f2234468f8
--- /dev/null
+++ b/gnuradio-core/src/lib/omnithread/Makefile.am
@@ -0,0 +1,67 @@
+#
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+include $(top_srcdir)/Makefile.common
+
+# This is the omnithread package,
+# extracted from the omniORB-4.0.1 distribution
+
+# we should do some configure hacking to determine these on the fly
+OMNITHREAD_DEFINES = -DPthreadDraftVersion=10
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(OMNITHREAD_DEFINES)
+
+noinst_LTLIBRARIES = libomnithread.la
+
+# At this point we only support the posix and nt pthreads i/f...
+
+if OMNITHREAD_POSIX
+libomnithread_la_SOURCES = \
+ posix.cc
+endif
+
+if OMNITHREAD_NT
+libomnithread_la_SOURCES = \
+ nt.cc
+endif
+
+libomnithread_la_LIBADD = \
+ $(PTHREAD_LIBS)
+
+# ... but this code also came with the package
+
+EXTRA_DIST = \
+ mach.cc \
+ nt.cc \
+ posix.cc \
+ solaris.cc \
+ threaddata.cc \
+ vxWorks.cc \
+ dir.mk
+
+grinclude_HEADERS = \
+ omnithread.h \
+ ot_mach.h \
+ ot_nt.h \
+ ot_posix.h \
+ ot_pthread_nt.h \
+ ot_solaris.h \
+ ot_VxThread.h
diff --git a/gnuradio-core/src/lib/omnithread/dir.mk b/gnuradio-core/src/lib/omnithread/dir.mk
new file mode 100644
index 0000000000..d53803417c
--- /dev/null
+++ b/gnuradio-core/src/lib/omnithread/dir.mk
@@ -0,0 +1,229 @@
+ifeq ($(ThreadSystem),Solaris)
+CXXSRCS = solaris.cc
+DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS)
+endif
+
+ifeq ($(ThreadSystem),Posix)
+CXXSRCS = posix.cc
+DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS) $(OMNITHREAD_POSIX_CPPFLAGS)
+endif
+
+ifeq ($(ThreadSystem),NT)
+CXXSRCS = nt.cc
+DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS)
+MSVC_STATICLIB_CXXNODEBUGFLAGS += -D_WINSTATIC
+MSVC_STATICLIB_CXXDEBUGFLAGS += -D_WINSTATIC
+MSVC_DLL_CXXNODEBUGFLAGS += -D_OMNITHREAD_DLL
+MSVC_DLL_CXXDEBUGFLAGS += -D_OMNITHREAD_DLL
+endif
+
+ifeq ($(ThreadSystem),NTPosix)
+CXXSRCS = posix.cc
+DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS)
+MSVC_STATICLIB_CXXNODEBUGFLAGS += -D_WINSTATIC
+MSVC_STATICLIB_CXXDEBUGFLAGS += -D_WINSTATIC
+MSVC_DLL_CXXNODEBUGFLAGS += -D_OMNITHREAD_DLL
+MSVC_DLL_CXXDEBUGFLAGS += -D_OMNITHREAD_DLL
+endif
+
+ifeq ($(ThreadSystem),Mach)
+CXXSRCS = mach.cc
+DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS)
+endif
+
+ifeq ($(ThreadSystem),vxWorks)
+CXXSRCS = vxWorks.cc
+OBJS = vxWorks.o
+DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS)
+endif
+
+LIB_NAME := omnithread
+LIB_VERSION := $(OMNITHREAD_VERSION)
+LIB_OBJS := $(CXXSRCS:.cc=.o)
+LIB_IMPORTS := $(OMNITHREAD_PLATFORM_LIB)
+
+all:: mkstatic mkshared
+
+export:: mkstatic mkshared
+
+ifdef INSTALLTARGET
+install:: mkstatic mkshared
+endif
+
+vers := $(subst ., ,$(LIB_VERSION))
+ifeq ($(words $(vers)), 2)
+ vers := _ $(vers)
+ major := ""
+else
+ major := $(word 1, $(vers))
+endif
+
+namespec := $(LIB_NAME) $(vers)
+
+##############################################################################
+# Build Static library
+##############################################################################
+
+ifndef NoStaticLibrary
+
+staticlib := static/$(patsubst %,$(LibNoDebugPattern),$(LIB_NAME)$(major))
+
+mkstatic::
+ @(dir=static; $(CreateDir))
+
+mkstatic:: $(staticlib)
+
+$(staticlib): $(patsubst %, static/%, $(LIB_OBJS))
+ @$(StaticLinkLibrary)
+
+export:: $(staticlib)
+ @$(ExportLibrary)
+
+ifdef INSTALLTARGET
+install:: $(staticlib)
+ @$(InstallLibrary)
+endif
+
+clean::
+ $(RM) static/*.o
+ $(RM) $(staticlib)
+
+veryclean::
+ $(RM) static/*.o
+ $(RM) $(staticlib)
+
+else
+
+mkstatic::
+
+endif
+
+
+##############################################################################
+# Build Shared library
+##############################################################################
+ifdef BuildSharedLibrary
+
+shlib := shared/$(shell $(SharedLibraryFullName) $(namespec))
+
+ifdef Win32Platform
+# in case of Win32 lossage:
+ imps := $(patsubst $(DLLDebugSearchPattern),$(DLLNoDebugSearchPattern), \
+ $(LIB_IMPORTS))
+else
+ imps := $(LIB_IMPORTS)
+endif
+
+mkshared::
+ @(dir=shared; $(CreateDir))
+
+mkshared:: $(shlib)
+
+$(shlib): $(patsubst %, shared/%, $(LIB_OBJS))
+ @(namespec="$(namespec)" extralibs="$(imps)" nodeffile=1; \
+ $(MakeCXXSharedLibrary))
+
+export:: $(shlib)
+ @(namespec="$(namespec)"; \
+ $(ExportSharedLibrary))
+
+ifdef INSTALLTARGET
+install:: $(shlib)
+ @(namespec="$(namespec)"; \
+ $(InstallSharedLibrary))
+endif
+
+clean::
+ $(RM) shared/*.o
+ (dir=shared; $(CleanSharedLibrary))
+
+veryclean::
+ $(RM) shared/*.o
+ @(dir=shared; $(CleanSharedLibrary))
+
+else
+
+mkshared::
+
+endif
+
+##############################################################################
+# Build debug libraries for Win32
+##############################################################################
+ifdef Win32Platform
+
+ifdef BuildSharedLibrary
+
+all:: mkstaticdbug mkshareddbug
+
+export:: mkstaticdbug mkshareddbug
+
+else
+
+all:: mkstaticdbug
+
+export:: mkstaticdbug
+
+endif
+
+
+#####################################################
+# Static debug libraries
+#####################################################
+
+dbuglib := debug/$(patsubst %,$(LibDebugPattern),$(LIB_NAME)$(major))
+
+mkstaticdbug::
+ @(dir=debug; $(CreateDir))
+
+mkstaticdbug:: $(dbuglib)
+
+$(dbuglib): $(patsubst %, debug/%, $(LIB_OBJS))
+ @$(StaticLinkLibrary)
+
+export:: $(dbuglib)
+ @$(ExportLibrary)
+
+clean::
+ $(RM) debug/*.o
+ $(RM) $(dbuglib)
+
+veryclean::
+ $(RM) debug/*.o
+ $(RM) $(dbuglib)
+
+#####################################################
+# DLL debug libraries
+#####################################################
+
+ifdef BuildSharedLibrary
+
+dbugshlib := shareddebug/$(shell $(SharedLibraryDebugFullName) $(namespec))
+
+dbugimps := $(patsubst $(DLLNoDebugSearchPattern),$(DLLDebugSearchPattern), \
+ $(LIB_IMPORTS))
+
+mkshareddbug::
+ @(dir=shareddebug; $(CreateDir))
+
+mkshareddbug:: $(dbugshlib)
+
+$(dbugshlib): $(patsubst %, shareddebug/%, $(LIB_OBJS))
+ (namespec="$(namespec)" debug=1 extralibs="$(dbugimps)" nodeffile=1; \
+ $(MakeCXXSharedLibrary))
+
+export:: $(dbugshlib)
+ @(namespec="$(namespec)" debug=1; \
+ $(ExportSharedLibrary))
+
+clean::
+ $(RM) shareddebug/*.o
+ @(dir=shareddebug; $(CleanSharedLibrary))
+
+veryclean::
+ $(RM) shareddebug/*.o
+ @(dir=shareddebug; $(CleanSharedLibrary))
+
+endif
+endif
+
diff --git a/gnuradio-core/src/lib/omnithread/mach.cc b/gnuradio-core/src/lib/omnithread/mach.cc
new file mode 100644
index 0000000000..06f8a11e11
--- /dev/null
+++ b/gnuradio-core/src/lib/omnithread/mach.cc
@@ -0,0 +1,714 @@
+// Package : omnithread
+// omnithread/mach.cc Created : 7/97 lars immisch lars@ibp.de
+//
+// Copyright (C) 1997 Immisch, Becker & Partner
+//
+// This file is part of the omnithread library
+//
+// The omnithread library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA
+//
+
+//
+// Implementation of OMNI thread abstraction for mach threads
+//
+// to the author's pleasure, mach cthreads are very similar to posix threads
+//
+
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <mach/cthreads.h>
+#include "omnithread.h"
+
+#define DB(x) // x
+// #include <iostream> or #include <iostream.h> if DB is on.
+
+#define ERRNO(x) (x)
+
+//
+// static variables
+//
+
+int omni_thread::init_t::count = 0;
+
+omni_mutex* omni_thread::next_id_mutex;
+int omni_thread::next_id = 0;
+
+static int normal_priority;
+static int highest_priority;
+
+static size_t stack_size = 0;
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Mutex
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_mutex::omni_mutex(void)
+{
+ mutex_init(&mach_mutex);
+}
+
+
+omni_mutex::~omni_mutex(void)
+{
+ mutex_clear(&mach_mutex);
+}
+
+
+void omni_mutex::lock(void)
+{
+ mutex_lock(&mach_mutex);
+}
+
+
+void omni_mutex::unlock(void)
+{
+ mutex_unlock(&mach_mutex);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Condition variable
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_condition::omni_condition(omni_mutex* m) : mutex(m)
+{
+ condition_init(&mach_cond);
+}
+
+
+omni_condition::~omni_condition(void)
+{
+ condition_clear(&mach_cond);
+}
+
+void
+omni_condition::wait(void)
+{
+ condition_wait(&mach_cond, &mutex->mach_mutex);
+}
+
+typedef struct alarmclock_args {
+ unsigned long secs;
+ unsigned long nsecs;
+ bool wakeup;
+ condition_t condition;
+ mutex_t mutex;
+};
+
+any_t alarmclock(any_t arg)
+{
+ alarmclock_args* alarm = (alarmclock_args*)arg;
+
+ omni_thread::sleep(alarm->secs, alarm->nsecs);
+
+ mutex_lock(alarm->mutex);
+
+ alarm->wakeup = TRUE;
+
+ condition_signal(alarm->condition);
+
+ mutex_unlock(alarm->mutex);
+
+ return (any_t)TRUE;
+}
+
+int omni_condition::timedwait(unsigned long abs_secs, unsigned long abs_nsecs)
+{
+ alarmclock_args alarm;
+
+ omni_thread::get_time(&alarm.secs, &alarm.nsecs, 0, 0);
+
+ if (abs_secs < alarm.secs || (abs_secs == alarm.secs && abs_nsecs <= alarm.nsecs))
+ return ETIMEDOUT;
+
+ alarm.secs = abs_secs - alarm.secs;
+ if (abs_nsecs <= alarm.nsecs) {
+ alarm.nsecs = 1000000 - alarm.nsecs + abs_nsecs;
+ alarm.secs--;
+ }
+ else {
+ alarm.nsecs = abs_nsecs - alarm.nsecs;
+ }
+
+ alarm.mutex = &mutex->mach_mutex;
+ alarm.condition = &mach_cond;
+ alarm.wakeup = FALSE;
+
+ cthread_t ct = cthread_fork((cthread_fn_t)alarmclock, (any_t)&alarm);
+ cthread_detach(ct);
+
+ condition_wait(&mach_cond, &mutex->mach_mutex);
+
+ if (alarm.wakeup) {
+ return 0;
+ }
+
+ // interrupt the alarmclock thread sleep
+ cthread_abort(ct);
+
+ // wait until it has signalled the condition
+ condition_wait(&mach_cond, &mutex->mach_mutex);
+
+ return 1;
+}
+
+
+void omni_condition::signal(void)
+{
+ condition_signal(&mach_cond);
+}
+
+
+void omni_condition::broadcast(void)
+{
+ condition_signal(&mach_cond);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Counting semaphore
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_semaphore::omni_semaphore(unsigned int initial) : c(&m)
+{
+ value = initial;
+}
+
+
+omni_semaphore::~omni_semaphore(void)
+{
+}
+
+
+void
+omni_semaphore::wait(void)
+{
+ omni_mutex_lock l(m);
+
+ while (value == 0)
+ c.wait();
+
+ value--;
+}
+
+
+int
+omni_semaphore::trywait(void)
+{
+ omni_mutex_lock l(m);
+
+ if (value == 0)
+ return 0;
+
+ value--;
+ return 1;
+}
+
+
+void
+omni_semaphore::post(void)
+{
+ omni_mutex_lock l(m);
+
+ if (value == 0)
+ c.signal();
+
+ value++;
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Thread
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+
+//
+// Initialisation function (gets called before any user code).
+//
+
+omni_thread::init_t::init_t(void)
+{
+ if (count++ != 0) // only do it once however many objects get created.
+ return;
+
+ //
+ // find base and max priority.
+ // This is the initial thread, so the max priority of this
+ // thread also applies to any newly created thread.
+ //
+
+ kern_return_t error;
+ struct thread_sched_info info;
+ unsigned int info_count = THREAD_SCHED_INFO_COUNT;
+
+ error = thread_info(thread_self(), THREAD_SCHED_INFO, (thread_info_t)&info, &info_count);
+ if (error != KERN_SUCCESS) {
+ DB(cerr << "omni_thread::init: error determining thread_info" << endl);
+ ::exit(1);
+ }
+ else {
+ normal_priority = info.base_priority;
+ highest_priority = info.max_priority;
+ }
+
+ next_id_mutex = new omni_mutex;
+
+ //
+ // Create object for this (i.e. initial) thread.
+ //
+
+ omni_thread* t = new omni_thread;
+
+ if (t->_state != STATE_NEW) {
+ DB(cerr << "omni_thread::init: problem creating initial thread object\n");
+ ::exit(1);
+ }
+
+ t->_state = STATE_RUNNING;
+
+ t->mach_thread = cthread_self();
+
+ DB(cerr << "initial thread " << t->id() << endl);
+
+ cthread_set_data(t->mach_thread, (any_t)t);
+}
+
+
+//
+// Wrapper for thread creation.
+//
+
+extern "C" void*
+omni_thread_wrapper(void* ptr)
+{
+ omni_thread* me = (omni_thread*)ptr;
+
+ DB(cerr << "omni_thread::wrapper: thread " << me->id()
+ << " started\n");
+
+ cthread_set_data(cthread_self(), (any_t)me);
+
+ //
+ // Now invoke the thread function with the given argument.
+ //
+
+ if (me->fn_void != NULL) {
+ (*me->fn_void)(me->thread_arg);
+ omni_thread::exit();
+ }
+
+ if (me->fn_ret != NULL) {
+ void* return_value = (*me->fn_ret)(me->thread_arg);
+ omni_thread::exit(return_value);
+ }
+
+ if (me->detached) {
+ me->run(me->thread_arg);
+ omni_thread::exit();
+ } else {
+ void* return_value = me->run_undetached(me->thread_arg);
+ omni_thread::exit(return_value);
+ }
+
+ // should never get here.
+
+ return NULL;
+}
+
+
+//
+// Constructors for omni_thread - set up the thread object but don't
+// start it running.
+//
+
+// construct a detached thread running a given function.
+
+omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri)
+{
+ common_constructor(arg, pri, 1);
+ fn_void = fn;
+ fn_ret = NULL;
+}
+
+// construct an undetached thread running a given function.
+
+omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri)
+{
+ common_constructor(arg, pri, 0);
+ fn_void = NULL;
+ fn_ret = fn;
+}
+
+// construct a thread which will run either run() or run_undetached().
+
+omni_thread::omni_thread(void* arg, priority_t pri)
+{
+ common_constructor(arg, pri, 1);
+ fn_void = NULL;
+ fn_ret = NULL;
+}
+
+// common part of all constructors.
+
+void omni_thread::common_constructor(void* arg, priority_t pri, int det)
+{
+ _state = STATE_NEW;
+ _priority = pri;
+
+ next_id_mutex->lock();
+ _id = next_id++;
+ next_id_mutex->unlock();
+
+ thread_arg = arg;
+ detached = det; // may be altered in start_undetached()
+
+ _dummy = 0;
+ _values = 0;
+ _value_alloc = 0;
+ // posix_thread is set up in initialisation routine or start().
+}
+
+
+//
+// Destructor for omni_thread.
+//
+
+omni_thread::~omni_thread(void)
+{
+ DB(cerr << "destructor called for thread " << id() << endl);
+ if (_values) {
+ for (key_t i=0; i < _value_alloc; i++) {
+ if (_values[i]) {
+ delete _values[i];
+ }
+ }
+ delete [] _values;
+ }
+}
+
+
+//
+// Start the thread
+//
+
+void
+omni_thread::start(void)
+{
+ omni_mutex_lock l(mutex);
+
+ int rc;
+
+ if (_state != STATE_NEW)
+ throw omni_thread_invalid();
+
+ mach_thread = cthread_fork(omni_thread_wrapper, (any_t)this);
+
+ _state = STATE_RUNNING;
+
+ if (detached) {
+ cthread_detach(mach_thread);
+ }
+}
+
+//
+// Start a thread which will run the member function run_undetached().
+//
+
+void
+omni_thread::start_undetached(void)
+{
+ if ((fn_void != NULL) || (fn_ret != NULL))
+ throw omni_thread_invalid();
+
+ detached = 0;
+ start();
+}
+
+
+//
+// join - simply check error conditions & call cthread_join.
+//
+
+void
+omni_thread::join(void** status)
+{
+ mutex.lock();
+
+ if ((_state != STATE_RUNNING) && (_state != STATE_TERMINATED)) {
+ mutex.unlock();
+ throw omni_thread_invalid();
+ }
+
+ mutex.unlock();
+
+ if (this == self())
+ throw omni_thread_invalid();
+
+ if (detached)
+ throw omni_thread_invalid();
+
+ DB(cerr << "omni_thread::join: doing cthread_join\n");
+
+ *status = cthread_join(mach_thread);
+
+ delete this;
+}
+
+
+//
+// Change this thread's priority.
+//
+
+void
+omni_thread::set_priority(priority_t pri)
+{
+ omni_mutex_lock l(mutex);
+
+ if (_state != STATE_RUNNING)
+ throw omni_thread_invalid();
+
+ _priority = pri;
+
+ kern_return_t rc = cthread_priority(mach_thread, mach_priority(pri), FALSE);
+
+ if (rc != KERN_SUCCESS)
+ throw omni_thread_fatal(errno);
+}
+
+//
+// create - construct a new thread object and start it running. Returns thread
+// object if successful, null pointer if not.
+//
+
+// detached version
+
+omni_thread*
+omni_thread::create(void (*fn)(void*), void* arg, priority_t pri)
+{
+ omni_thread* t = new omni_thread(fn, arg, pri);
+
+ t->start();
+
+ return t;
+}
+
+// undetached version
+
+omni_thread*
+omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri)
+{
+ omni_thread* t = new omni_thread(fn, arg, pri);
+
+ t->start();
+
+ return t;
+}
+
+//
+// exit() _must_ lock the mutex even in the case of a detached thread. This is
+// because a thread may run to completion before the thread that created it has
+// had a chance to get out of start(). By locking the mutex we ensure that the
+// creating thread must have reached the end of start() before we delete the
+// thread object. Of course, once the call to start() returns, the user can
+// still incorrectly refer to the thread object, but that's their problem.
+//
+
+void omni_thread::exit(void* return_value)
+{
+ omni_thread* me = self();
+
+ if (me)
+ {
+ me->mutex.lock();
+
+ if (me->_state != STATE_RUNNING)
+ DB(cerr << "omni_thread::exit: thread not in \"running\" state\n");
+
+ me->_state = STATE_TERMINATED;
+
+ me->mutex.unlock();
+
+ DB(cerr << "omni_thread::exit: thread " << me->id() << " detached "
+ << me->detached << " return value " << return_value << endl);
+
+ if (me->detached)
+ delete me;
+ }
+ else
+ {
+ DB(cerr << "omni_thread::exit: called with a non-omnithread. Exit quietly." << endl);
+ }
+ cthread_exit(return_value);
+}
+
+omni_thread* omni_thread::self(void)
+{
+ omni_thread* me;
+
+ me = (omni_thread*)cthread_data(cthread_self());
+
+ if (!me) {
+ // This thread is not created by omni_thread::start because it
+ // doesn't has a class omni_thread instance attached to its key.
+ DB(cerr << "omni_thread::self: called with a non-ominthread. NULL is returned." << endl);
+ }
+
+ return me;
+}
+
+void omni_thread::yield(void)
+{
+ cthread_yield();
+}
+
+#define MAX_SLEEP_SECONDS (unsigned)4294966 // (2**32-2)/1000
+
+void
+omni_thread::sleep(unsigned long secs, unsigned long nanosecs)
+{
+ if (secs <= MAX_SLEEP_SECONDS) {
+ thread_switch(THREAD_NULL, SWITCH_OPTION_WAIT, secs * 1000 + nanosecs / 1000000);
+ return;
+ }
+
+ unsigned no_of_max_sleeps = secs / MAX_SLEEP_SECONDS;
+
+ for (unsigned i = 0; i < no_of_max_sleeps; i++)
+ thread_switch(THREAD_NULL, SWITCH_OPTION_WAIT, MAX_SLEEP_SECONDS * 1000);
+
+ thread_switch(THREAD_NULL, SWITCH_OPTION_WAIT,
+ (secs % MAX_SLEEP_SECONDS) * 1000 + nanosecs / 1000000);
+
+ return;
+}
+
+void
+omni_thread::get_time(unsigned long* abs_sec, unsigned long* abs_nsec,
+ unsigned long rel_sec, unsigned long rel_nsec)
+{
+ int rc;
+ unsigned long tv_sec;
+ unsigned long tv_nsec;
+ struct timeval tv;
+
+ rc = gettimeofday(&tv, NULL);
+ if (rc) throw omni_thread_fatal(rc);
+
+ tv_sec = tv.tv_sec;
+ tv_nsec = tv.tv_usec * 1000;
+
+ tv_nsec += rel_nsec;
+ tv_sec += rel_sec + tv_nsec / 1000000000;
+ tv_nsec = tv_nsec % 1000000000;
+
+ *abs_sec = tv_sec;
+ *abs_nsec = tv_nsec;
+}
+
+
+int
+omni_thread::mach_priority(priority_t pri)
+{
+ switch (pri) {
+
+ case PRIORITY_LOW:
+ return 0;
+
+ case PRIORITY_NORMAL:
+ return normal_priority;
+
+ case PRIORITY_HIGH:
+ return highest_priority;
+
+ default:
+ return -1;
+ }
+}
+
+void
+omni_thread::stacksize(unsigned long sz)
+{
+ stack_size = sz;
+}
+
+unsigned long
+omni_thread::stacksize()
+{
+ return stack_size;
+}
+
+
+//
+// Dummy thread
+//
+
+#error This dummy thread code is not tested. It might work if you're lucky.
+
+class omni_thread_dummy : public omni_thread {
+public:
+ inline omni_thread_dummy() : omni_thread()
+ {
+ _dummy = 1;
+ _state = STATE_RUNNING;
+ mach_thread = cthread_self();
+ cthread_set_data(mach_thread, (any_t)this));
+ }
+ inline ~omni_thread_dummy()
+ {
+ cthread_set_data(mach_thread, (any_t)0));
+ }
+};
+
+omni_thread*
+omni_thread::create_dummy()
+{
+ if (omni_thread::self())
+ throw omni_thread_invalid();
+
+ return new omni_thread_dummy;
+}
+
+void
+omni_thread::release_dummy()
+{
+ omni_thread* self = omni_thread::self();
+ if (!self || !self->_dummy)
+ throw omni_thread_invalid();
+
+ omni_thread_dummy* dummy = (omni_thread_dummy*)self;
+ delete dummy;
+}
+
+
+#define INSIDE_THREAD_IMPL_CC
+#include "threaddata.cc"
+#undef INSIDE_THREAD_IMPL_CC
diff --git a/gnuradio-core/src/lib/omnithread/nt.cc b/gnuradio-core/src/lib/omnithread/nt.cc
new file mode 100644
index 0000000000..09be422917
--- /dev/null
+++ b/gnuradio-core/src/lib/omnithread/nt.cc
@@ -0,0 +1,967 @@
+// Package : omnithread
+// omnithread/nt.cc Created : 6/95 tjr
+//
+// Copyright (C) 2006 Free Software Foundation, Inc.
+// Copyright (C) 1995-1999 AT&T Laboratories Cambridge
+//
+// This file is part of the omnithread library
+//
+// The omnithread library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA
+//
+
+//
+// Implementation of OMNI thread abstraction for NT threads
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <errno.h>
+#include <omnithread.h>
+#include <process.h>
+
+#define DB(x) // x
+//#include <iostream.h> or #include <iostream> if DB is on.
+
+static void get_time_now(unsigned long* abs_sec, unsigned long* abs_nsec);
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Mutex
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_mutex::omni_mutex(void)
+{
+ InitializeCriticalSection(&crit);
+}
+
+omni_mutex::~omni_mutex(void)
+{
+ DeleteCriticalSection(&crit);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Condition variable
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//
+// Condition variables are tricky to implement using NT synchronisation
+// primitives, since none of them have the atomic "release mutex and wait to be
+// signalled" which is central to the idea of a condition variable. To get
+// around this the solution is to record which threads are waiting and
+// explicitly wake up those threads.
+//
+// Here we implement a condition variable using a list of waiting threads
+// (protected by a critical section), and a per-thread semaphore (which
+// actually only needs to be a binary semaphore).
+//
+// To wait on the cv, a thread puts itself on the list of waiting threads for
+// that cv, then releases the mutex and waits on its own personal semaphore. A
+// signalling thread simply takes a thread from the head of the list and kicks
+// that thread's semaphore. Broadcast is simply implemented by kicking the
+// semaphore of each waiting thread.
+//
+// The only other tricky part comes when a thread gets a timeout from a timed
+// wait on its semaphore. Between returning with a timeout from the wait and
+// entering the critical section, a signalling thread could get in, kick the
+// waiting thread's semaphore and remove it from the list. If this happens,
+// the waiting thread's semaphore is now out of step so it needs resetting, and
+// the thread should indicate that it was signalled rather than that it timed
+// out.
+//
+// It is possible that the thread calling wait or timedwait is not a
+// omni_thread. In this case we have to provide a temporary data structure,
+// i.e. for the duration of the call, for the thread to link itself on the
+// list of waiting threads. _internal_omni_thread_dummy provides such
+// a data structure and _internal_omni_thread_helper is a helper class to
+// deal with this special case for wait() and timedwait(). Once created,
+// the _internal_omni_thread_dummy is cached for use by the next wait() or
+// timedwait() call from a non-omni_thread. This is probably worth doing
+// because creating a Semaphore is quite heavy weight.
+
+class _internal_omni_thread_helper;
+
+class _internal_omni_thread_dummy : public omni_thread {
+public:
+ inline _internal_omni_thread_dummy() : next(0) { }
+ inline ~_internal_omni_thread_dummy() { }
+ friend class _internal_omni_thread_helper;
+private:
+ _internal_omni_thread_dummy* next;
+};
+
+class _internal_omni_thread_helper {
+public:
+ inline _internal_omni_thread_helper() {
+ d = 0;
+ t = omni_thread::self();
+ if (!t) {
+ omni_mutex_lock sync(cachelock);
+ if (cache) {
+ d = cache;
+ cache = cache->next;
+ }
+ else {
+ d = new _internal_omni_thread_dummy;
+ }
+ t = d;
+ }
+ }
+ inline ~_internal_omni_thread_helper() {
+ if (d) {
+ omni_mutex_lock sync(cachelock);
+ d->next = cache;
+ cache = d;
+ }
+ }
+ inline operator omni_thread* () { return t; }
+ inline omni_thread* operator->() { return t; }
+
+ static _internal_omni_thread_dummy* cache;
+ static omni_mutex cachelock;
+
+private:
+ _internal_omni_thread_dummy* d;
+ omni_thread* t;
+};
+
+_internal_omni_thread_dummy* _internal_omni_thread_helper::cache = 0;
+omni_mutex _internal_omni_thread_helper::cachelock;
+
+
+omni_condition::omni_condition(omni_mutex* m) : mutex(m)
+{
+ InitializeCriticalSection(&crit);
+ waiting_head = waiting_tail = NULL;
+}
+
+
+omni_condition::~omni_condition(void)
+{
+ DeleteCriticalSection(&crit);
+ DB( if (waiting_head != NULL) {
+ cerr << "omni_condition::~omni_condition: list of waiting threads "
+ << "is not empty\n";
+ } )
+}
+
+
+void
+omni_condition::wait(void)
+{
+ _internal_omni_thread_helper me;
+
+ EnterCriticalSection(&crit);
+
+ me->cond_next = NULL;
+ me->cond_prev = waiting_tail;
+ if (waiting_head == NULL)
+ waiting_head = me;
+ else
+ waiting_tail->cond_next = me;
+ waiting_tail = me;
+ me->cond_waiting = TRUE;
+
+ LeaveCriticalSection(&crit);
+
+ mutex->unlock();
+
+ DWORD result = WaitForSingleObject(me->cond_semaphore, INFINITE);
+
+ mutex->lock();
+
+ if (result != WAIT_OBJECT_0)
+ throw omni_thread_fatal(GetLastError());
+}
+
+
+int
+omni_condition::timedwait(unsigned long abs_sec, unsigned long abs_nsec)
+{
+ _internal_omni_thread_helper me;
+
+ EnterCriticalSection(&crit);
+
+ me->cond_next = NULL;
+ me->cond_prev = waiting_tail;
+ if (waiting_head == NULL)
+ waiting_head = me;
+ else
+ waiting_tail->cond_next = me;
+ waiting_tail = me;
+ me->cond_waiting = TRUE;
+
+ LeaveCriticalSection(&crit);
+
+ mutex->unlock();
+
+ unsigned long now_sec, now_nsec;
+
+ get_time_now(&now_sec, &now_nsec);
+
+ DWORD timeout;
+ if ((abs_sec <= now_sec) && ((abs_sec < now_sec) || (abs_nsec < now_nsec)))
+ timeout = 0;
+ else {
+ timeout = (abs_sec-now_sec) * 1000;
+
+ if( abs_nsec < now_nsec ) timeout -= (now_nsec-abs_nsec) / 1000000;
+ else timeout += (abs_nsec-now_nsec) / 1000000;
+ }
+
+ DWORD result = WaitForSingleObject(me->cond_semaphore, timeout);
+
+ if (result == WAIT_TIMEOUT) {
+ EnterCriticalSection(&crit);
+
+ if (me->cond_waiting) {
+ if (me->cond_prev != NULL)
+ me->cond_prev->cond_next = me->cond_next;
+ else
+ waiting_head = me->cond_next;
+ if (me->cond_next != NULL)
+ me->cond_next->cond_prev = me->cond_prev;
+ else
+ waiting_tail = me->cond_prev;
+ me->cond_waiting = FALSE;
+
+ LeaveCriticalSection(&crit);
+
+ mutex->lock();
+ return 0;
+ }
+
+ //
+ // We timed out but another thread still signalled us. Wait for
+ // the semaphore (it _must_ have been signalled) to decrement it
+ // again. Return that we were signalled, not that we timed out.
+ //
+
+ LeaveCriticalSection(&crit);
+
+ result = WaitForSingleObject(me->cond_semaphore, INFINITE);
+ }
+
+ if (result != WAIT_OBJECT_0)
+ throw omni_thread_fatal(GetLastError());
+
+ mutex->lock();
+ return 1;
+}
+
+
+void
+omni_condition::signal(void)
+{
+ EnterCriticalSection(&crit);
+
+ if (waiting_head != NULL) {
+ omni_thread* t = waiting_head;
+ waiting_head = t->cond_next;
+ if (waiting_head == NULL)
+ waiting_tail = NULL;
+ else
+ waiting_head->cond_prev = NULL;
+ t->cond_waiting = FALSE;
+
+ if (!ReleaseSemaphore(t->cond_semaphore, 1, NULL)) {
+ int rc = GetLastError();
+ LeaveCriticalSection(&crit);
+ throw omni_thread_fatal(rc);
+ }
+ }
+
+ LeaveCriticalSection(&crit);
+}
+
+
+void
+omni_condition::broadcast(void)
+{
+ EnterCriticalSection(&crit);
+
+ while (waiting_head != NULL) {
+ omni_thread* t = waiting_head;
+ waiting_head = t->cond_next;
+ if (waiting_head == NULL)
+ waiting_tail = NULL;
+ else
+ waiting_head->cond_prev = NULL;
+ t->cond_waiting = FALSE;
+
+ if (!ReleaseSemaphore(t->cond_semaphore, 1, NULL)) {
+ int rc = GetLastError();
+ LeaveCriticalSection(&crit);
+ throw omni_thread_fatal(rc);
+ }
+ }
+
+ LeaveCriticalSection(&crit);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Counting semaphore
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#define SEMAPHORE_MAX 0x7fffffff
+
+
+omni_semaphore::omni_semaphore(unsigned int initial, unsigned int max_count)
+{
+ if (max_count > SEMAPHORE_MAX)
+ max_count= SEMAPHORE_MAX;
+
+ nt_sem = CreateSemaphore(NULL, initial, max_count, NULL);
+
+ if (nt_sem == NULL) {
+ DB( cerr << "omni_semaphore::omni_semaphore: CreateSemaphore error "
+ << GetLastError() << endl );
+ throw omni_thread_fatal(GetLastError());
+ }
+}
+
+
+omni_semaphore::~omni_semaphore(void)
+{
+ if (!CloseHandle(nt_sem)) {
+ DB( cerr << "omni_semaphore::~omni_semaphore: CloseHandle error "
+ << GetLastError() << endl );
+ throw omni_thread_fatal(GetLastError());
+ }
+}
+
+
+void
+omni_semaphore::wait(void)
+{
+ if (WaitForSingleObject(nt_sem, INFINITE) != WAIT_OBJECT_0)
+ throw omni_thread_fatal(GetLastError());
+}
+
+
+int
+omni_semaphore::trywait(void)
+{
+ switch (WaitForSingleObject(nt_sem, 0)) {
+
+ case WAIT_OBJECT_0:
+ return 1;
+ case WAIT_TIMEOUT:
+ return 0;
+ }
+
+ throw omni_thread_fatal(GetLastError());
+ return 0; /* keep msvc++ happy */
+}
+
+
+void
+omni_semaphore::post(void)
+{
+ if (!ReleaseSemaphore(nt_sem, 1, NULL))
+ throw omni_thread_fatal(GetLastError());
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Thread
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//
+// Static variables
+//
+
+omni_mutex* omni_thread::next_id_mutex;
+int omni_thread::next_id = 0;
+static DWORD self_tls_index;
+
+static unsigned int stack_size = 0;
+
+//
+// Initialisation function (gets called before any user code).
+//
+
+static int& count() {
+ static int the_count = 0;
+ return the_count;
+}
+
+omni_thread::init_t::init_t(void)
+{
+ if (count()++ != 0) // only do it once however many objects get created.
+ return;
+
+ DB(cerr << "omni_thread::init: NT implementation initialising\n");
+
+ self_tls_index = TlsAlloc();
+
+ if (self_tls_index == 0xffffffff)
+ throw omni_thread_fatal(GetLastError());
+
+ next_id_mutex = new omni_mutex;
+
+ //
+ // Create object for this (i.e. initial) thread.
+ //
+
+ omni_thread* t = new omni_thread;
+
+ t->_state = STATE_RUNNING;
+
+ if (!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
+ GetCurrentProcess(), &t->handle,
+ 0, FALSE, DUPLICATE_SAME_ACCESS))
+ throw omni_thread_fatal(GetLastError());
+
+ t->nt_id = GetCurrentThreadId();
+
+ DB(cerr << "initial thread " << t->id() << " NT thread id " << t->nt_id
+ << endl);
+
+ if (!TlsSetValue(self_tls_index, (LPVOID)t))
+ throw omni_thread_fatal(GetLastError());
+
+ if (!SetThreadPriority(t->handle, nt_priority(PRIORITY_NORMAL)))
+ throw omni_thread_fatal(GetLastError());
+}
+
+omni_thread::init_t::~init_t(void)
+{
+ if (--count() != 0) return;
+
+ omni_thread* self = omni_thread::self();
+ if (!self) return;
+
+ TlsSetValue(self_tls_index, (LPVOID)0);
+ delete self;
+
+ delete next_id_mutex;
+
+ TlsFree(self_tls_index);
+}
+
+//
+// Wrapper for thread creation.
+//
+
+extern "C"
+#ifndef __BCPLUSPLUS__
+unsigned __stdcall
+#else
+void _USERENTRY
+#endif
+omni_thread_wrapper(void* ptr)
+{
+ omni_thread* me = (omni_thread*)ptr;
+
+ DB(cerr << "omni_thread_wrapper: thread " << me->id()
+ << " started\n");
+
+ if (!TlsSetValue(self_tls_index, (LPVOID)me))
+ throw omni_thread_fatal(GetLastError());
+
+ //
+ // Now invoke the thread function with the given argument.
+ //
+
+ if (me->fn_void != NULL) {
+ (*me->fn_void)(me->thread_arg);
+ omni_thread::exit();
+ }
+
+ if (me->fn_ret != NULL) {
+ void* return_value = (*me->fn_ret)(me->thread_arg);
+ omni_thread::exit(return_value);
+ }
+
+ if (me->detached) {
+ me->run(me->thread_arg);
+ omni_thread::exit();
+ } else {
+ void* return_value = me->run_undetached(me->thread_arg);
+ omni_thread::exit(return_value);
+ }
+
+ // should never get here.
+#ifndef __BCPLUSPLUS__
+ return 0;
+#endif
+}
+
+
+//
+// Constructors for omni_thread - set up the thread object but don't
+// start it running.
+//
+
+// construct a detached thread running a given function.
+
+omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri)
+{
+ common_constructor(arg, pri, 1);
+ fn_void = fn;
+ fn_ret = NULL;
+}
+
+// construct an undetached thread running a given function.
+
+omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri)
+{
+ common_constructor(arg, pri, 0);
+ fn_void = NULL;
+ fn_ret = fn;
+}
+
+// construct a thread which will run either run() or run_undetached().
+
+omni_thread::omni_thread(void* arg, priority_t pri)
+{
+ common_constructor(arg, pri, 1);
+ fn_void = NULL;
+ fn_ret = NULL;
+}
+
+// common part of all constructors.
+
+void
+omni_thread::common_constructor(void* arg, priority_t pri, int det)
+{
+ _state = STATE_NEW;
+ _priority = pri;
+
+ next_id_mutex->lock();
+ _id = next_id++;
+ next_id_mutex->unlock();
+
+ thread_arg = arg;
+ detached = det; // may be altered in start_undetached()
+
+ cond_semaphore = CreateSemaphore(NULL, 0, SEMAPHORE_MAX, NULL);
+
+ if (cond_semaphore == NULL)
+ throw omni_thread_fatal(GetLastError());
+
+ cond_next = cond_prev = NULL;
+ cond_waiting = FALSE;
+
+ handle = NULL;
+
+ _dummy = 0;
+ _values = 0;
+ _value_alloc = 0;
+}
+
+
+//
+// Destructor for omni_thread.
+//
+
+omni_thread::~omni_thread(void)
+{
+ DB(cerr << "destructor called for thread " << id() << endl);
+ if (_values) {
+ for (key_t i=0; i < _value_alloc; i++) {
+ if (_values[i]) {
+ delete _values[i];
+ }
+ }
+ delete [] _values;
+ }
+ if (handle && !CloseHandle(handle))
+ throw omni_thread_fatal(GetLastError());
+ if (cond_semaphore && !CloseHandle(cond_semaphore))
+ throw omni_thread_fatal(GetLastError());
+}
+
+
+//
+// Start the thread
+//
+
+void
+omni_thread::start(void)
+{
+ omni_mutex_lock l(mutex);
+
+ if (_state != STATE_NEW)
+ throw omni_thread_invalid();
+
+#ifndef __BCPLUSPLUS__
+ // MSVC++ or compatiable
+ unsigned int t;
+ handle = (HANDLE)_beginthreadex(
+ NULL,
+ stack_size,
+ omni_thread_wrapper,
+ (LPVOID)this,
+ CREATE_SUSPENDED,
+ &t);
+ nt_id = t;
+ if (handle == NULL)
+ throw omni_thread_fatal(GetLastError());
+#else
+ // Borland C++
+ handle = (HANDLE)_beginthreadNT(omni_thread_wrapper,
+ stack_size,
+ (void*)this,
+ NULL,
+ CREATE_SUSPENDED,
+ &nt_id);
+ if (handle == INVALID_HANDLE_VALUE)
+ throw omni_thread_fatal(errno);
+#endif
+
+ if (!SetThreadPriority(handle, nt_priority(_priority)))
+ throw omni_thread_fatal(GetLastError());
+
+ if (ResumeThread(handle) == 0xffffffff)
+ throw omni_thread_fatal(GetLastError());
+
+ _state = STATE_RUNNING;
+}
+
+
+//
+// Start a thread which will run the member function run_undetached().
+//
+
+void
+omni_thread::start_undetached(void)
+{
+ if ((fn_void != NULL) || (fn_ret != NULL))
+ throw omni_thread_invalid();
+
+ detached = 0;
+ start();
+}
+
+
+//
+// join - simply check error conditions & call WaitForSingleObject.
+//
+
+void
+omni_thread::join(void** status)
+{
+ mutex.lock();
+
+ if ((_state != STATE_RUNNING) && (_state != STATE_TERMINATED)) {
+ mutex.unlock();
+ throw omni_thread_invalid();
+ }
+
+ mutex.unlock();
+
+ if (this == self())
+ throw omni_thread_invalid();
+
+ if (detached)
+ throw omni_thread_invalid();
+
+ DB(cerr << "omni_thread::join: doing WaitForSingleObject\n");
+
+ if (WaitForSingleObject(handle, INFINITE) != WAIT_OBJECT_0)
+ throw omni_thread_fatal(GetLastError());
+
+ DB(cerr << "omni_thread::join: WaitForSingleObject succeeded\n");
+
+ if (status)
+ *status = return_val;
+
+ delete this;
+}
+
+
+//
+// Change this thread's priority.
+//
+
+void
+omni_thread::set_priority(priority_t pri)
+{
+ omni_mutex_lock l(mutex);
+
+ if (_state != STATE_RUNNING)
+ throw omni_thread_invalid();
+
+ _priority = pri;
+
+ if (!SetThreadPriority(handle, nt_priority(pri)))
+ throw omni_thread_fatal(GetLastError());
+}
+
+
+//
+// create - construct a new thread object and start it running. Returns thread
+// object if successful, null pointer if not.
+//
+
+// detached version
+
+omni_thread*
+omni_thread::create(void (*fn)(void*), void* arg, priority_t pri)
+{
+ omni_thread* t = new omni_thread(fn, arg, pri);
+ t->start();
+ return t;
+}
+
+// undetached version
+
+omni_thread*
+omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri)
+{
+ omni_thread* t = new omni_thread(fn, arg, pri);
+ t->start();
+ return t;
+}
+
+
+//
+// exit() _must_ lock the mutex even in the case of a detached thread. This is
+// because a thread may run to completion before the thread that created it has
+// had a chance to get out of start(). By locking the mutex we ensure that the
+// creating thread must have reached the end of start() before we delete the
+// thread object. Of course, once the call to start() returns, the user can
+// still incorrectly refer to the thread object, but that's their problem.
+//
+
+void
+omni_thread::exit(void* return_value)
+{
+ omni_thread* me = self();
+
+ if (me)
+ {
+ me->mutex.lock();
+
+ me->_state = STATE_TERMINATED;
+
+ me->mutex.unlock();
+
+ DB(cerr << "omni_thread::exit: thread " << me->id() << " detached "
+ << me->detached << " return value " << return_value << endl);
+
+ if (me->detached) {
+ delete me;
+ } else {
+ me->return_val = return_value;
+ }
+ }
+ else
+ {
+ DB(cerr << "omni_thread::exit: called with a non-omnithread. Exit quietly." << endl);
+ }
+#ifndef __BCPLUSPLUS__
+ // MSVC++ or compatiable
+ // _endthreadex() does not automatically closes the thread handle.
+ // The omni_thread dtor closes the thread handle.
+ _endthreadex(0);
+#else
+ // Borland C++
+ // _endthread() does not automatically closes the thread handle.
+ // _endthreadex() is only available if __MFC_COMPAT__ is defined and
+ // all it does is to call _endthread().
+ _endthread();
+#endif
+}
+
+
+omni_thread*
+omni_thread::self(void)
+{
+ LPVOID me;
+
+ me = TlsGetValue(self_tls_index);
+
+ if (me == NULL) {
+ DB(cerr << "omni_thread::self: called with a non-ominthread. NULL is returned." << endl);
+ }
+ return (omni_thread*)me;
+}
+
+
+void
+omni_thread::yield(void)
+{
+ Sleep(0);
+}
+
+
+#define MAX_SLEEP_SECONDS (DWORD)4294966 // (2**32-2)/1000
+
+void
+omni_thread::sleep(unsigned long secs, unsigned long nanosecs)
+{
+ if (secs <= MAX_SLEEP_SECONDS) {
+ Sleep(secs * 1000 + nanosecs / 1000000);
+ return;
+ }
+
+ DWORD no_of_max_sleeps = secs / MAX_SLEEP_SECONDS;
+
+ for (DWORD i = 0; i < no_of_max_sleeps; i++)
+ Sleep(MAX_SLEEP_SECONDS * 1000);
+
+ Sleep((secs % MAX_SLEEP_SECONDS) * 1000 + nanosecs / 1000000);
+}
+
+
+void
+omni_thread::get_time(unsigned long* abs_sec, unsigned long* abs_nsec,
+ unsigned long rel_sec, unsigned long rel_nsec)
+{
+ get_time_now(abs_sec, abs_nsec);
+ *abs_nsec += rel_nsec;
+ *abs_sec += rel_sec + *abs_nsec / 1000000000;
+ *abs_nsec = *abs_nsec % 1000000000;
+}
+
+
+int
+omni_thread::nt_priority(priority_t pri)
+{
+ switch (pri) {
+
+ case PRIORITY_LOW:
+ return THREAD_PRIORITY_LOWEST;
+
+ case PRIORITY_NORMAL:
+ return THREAD_PRIORITY_NORMAL;
+
+ case PRIORITY_HIGH:
+ return THREAD_PRIORITY_HIGHEST;
+ }
+
+ throw omni_thread_invalid();
+ return 0; /* keep msvc++ happy */
+}
+
+
+static void
+get_time_now(unsigned long* abs_sec, unsigned long* abs_nsec)
+{
+ static int days_in_preceding_months[12]
+ = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+ static int days_in_preceding_months_leap[12]
+ = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
+
+ SYSTEMTIME st;
+
+ GetSystemTime(&st);
+ *abs_nsec = st.wMilliseconds * 1000000;
+
+ // this formula should work until 1st March 2100
+
+ DWORD days = ((st.wYear - 1970) * 365 + (st.wYear - 1969) / 4
+ + ((st.wYear % 4)
+ ? days_in_preceding_months[st.wMonth - 1]
+ : days_in_preceding_months_leap[st.wMonth - 1])
+ + st.wDay - 1);
+
+ *abs_sec = st.wSecond + 60 * (st.wMinute + 60 * (st.wHour + 24 * days));
+}
+
+void
+omni_thread::stacksize(unsigned long sz)
+{
+ stack_size = sz;
+}
+
+unsigned long
+omni_thread::stacksize()
+{
+ return stack_size;
+}
+
+//
+// Dummy thread
+//
+
+class omni_thread_dummy : public omni_thread {
+public:
+ inline omni_thread_dummy() : omni_thread()
+ {
+ _dummy = 1;
+ _state = STATE_RUNNING;
+
+ if (!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
+ GetCurrentProcess(), &handle,
+ 0, FALSE, DUPLICATE_SAME_ACCESS))
+ throw omni_thread_fatal(GetLastError());
+
+ nt_id = GetCurrentThreadId();
+
+ if (!TlsSetValue(self_tls_index, (LPVOID)this))
+ throw omni_thread_fatal(GetLastError());
+ }
+ inline ~omni_thread_dummy()
+ {
+ if (!TlsSetValue(self_tls_index, (LPVOID)0))
+ throw omni_thread_fatal(GetLastError());
+ }
+};
+
+omni_thread*
+omni_thread::create_dummy()
+{
+ if (omni_thread::self())
+ throw omni_thread_invalid();
+
+ return new omni_thread_dummy;
+}
+
+void
+omni_thread::release_dummy()
+{
+ omni_thread* self = omni_thread::self();
+ if (!self || !self->_dummy)
+ throw omni_thread_invalid();
+
+ omni_thread_dummy* dummy = (omni_thread_dummy*)self;
+ delete dummy;
+}
+
+
+#if defined(__DMC__) && defined(_WINDLL)
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ return TRUE;
+}
+#endif
+
+
+#define INSIDE_THREAD_IMPL_CC
+#include "threaddata.cc"
+#undef INSIDE_THREAD_IMPL_CC
diff --git a/gnuradio-core/src/lib/omnithread/omnithread.h b/gnuradio-core/src/lib/omnithread/omnithread.h
new file mode 100644
index 0000000000..f63adc4fed
--- /dev/null
+++ b/gnuradio-core/src/lib/omnithread/omnithread.h
@@ -0,0 +1,622 @@
+// -*- Mode: C++; -*-
+// Package : omnithread
+// omnithread.h Created : 7/94 tjr
+//
+// Copyright (C) 2006 Free Software Foundation, Inc.
+// Copyright (C) 1994,1995,1996, 1997 Olivetti & Oracle Research Laboratory
+//
+// This file is part of the omnithread library
+//
+// The omnithread library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA
+//
+
+//
+// Interface to OMNI thread abstraction.
+//
+// This file declares classes for threads and synchronisation objects
+// (mutexes, condition variables and counting semaphores).
+//
+// Wherever a seemingly arbitrary choice has had to be made as to the interface
+// provided, the intention here has been to be as POSIX-like as possible. This
+// is why there is no semaphore timed wait, for example.
+//
+
+#ifndef __omnithread_h_
+#define __omnithread_h_
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+class omni_mutex;
+class omni_condition;
+class omni_semaphore;
+class omni_thread;
+
+//
+// OMNI_THREAD_EXPOSE can be defined as public or protected to expose the
+// implementation class - this may be useful for debugging. Hopefully this
+// won't change the underlying structure which the compiler generates so that
+// this can work without recompiling the library.
+//
+
+#ifndef OMNI_THREAD_EXPOSE
+#define OMNI_THREAD_EXPOSE private
+#endif
+
+//
+// Include implementation-specific header file.
+//
+// This must define 4 CPP macros of the form OMNI_x_IMPLEMENTATION for mutex,
+// condition variable, semaphore and thread. Each should define any
+// implementation-specific members of the corresponding classes.
+//
+
+
+//
+// For now, we assume they've always got a Posix Threads implementation.
+// If not, it'll take some configure hacking to sort it out, along with
+// the relevant libraries to link with, etc.
+//
+
+#if !defined(OMNITHREAD_POSIX) && !defined(OMNITHREAD_NT) && defined HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if defined(OMNITHREAD_POSIX)
+#include <ot_posix.h>
+
+#elif defined(OMNITHREAD_NT)
+#include <ot_nt.h>
+
+#ifdef _MSC_VER
+
+// Using MSVC++ to compile. If compiling library as a DLL,
+// define _OMNITHREAD_DLL. If compiling as a statuc library, define
+// _WINSTATIC
+// If compiling an application that is to be statically linked to omnithread,
+// define _WINSTATIC (if the application is to be dynamically linked,
+// there is no need to define any of these macros).
+
+#if defined (_OMNITHREAD_DLL) && defined(_WINSTATIC)
+#error "Both _OMNITHREAD_DLL and _WINSTATIC are defined."
+#elif defined(_OMNITHREAD_DLL)
+#define _OMNITHREAD_NTDLL_ __declspec(dllexport)
+#elif !defined(_WINSTATIC)
+#define _OMNITHREAD_NTDLL_ __declspec(dllimport)
+#elif defined(_WINSTATIC)
+#define _OMNITHREAD_NTDLL_
+#endif
+ // _OMNITHREAD_DLL && _WINSTATIC
+
+#else
+
+// Not using MSVC++ to compile
+#define _OMNITHREAD_NTDLL_
+
+#endif
+ // _MSC_VER
+
+#elif defined(__vxWorks__)
+#include <ot_VxThread.h>
+
+#elif defined(__sunos__)
+#if __OSVERSION__ != 5
+// XXX Workaround for SUN C++ compiler (seen on 4.2) Template.DB code
+// regeneration bug. See omniORB2/CORBA_sysdep.h for details.
+#if !defined(__SUNPRO_CC) || __OSVERSION__ != '5'
+#error "Only SunOS 5.x or later is supported."
+#endif
+#endif
+#ifdef UseSolarisThreads
+#include <ot_solaris.h>
+#else
+#include <ot_posix.h>
+#endif
+
+#elif defined(__rtems__)
+#include <ot_posix.h>
+#include <sched.h>
+
+#elif defined(__macos__)
+#include <ot_posix.h>
+#include <sched.h>
+
+#else
+#error "No implementation header file"
+#endif
+
+
+#if !defined(__WIN32__)
+#define _OMNITHREAD_NTDLL_
+#endif
+
+#if (!defined(OMNI_MUTEX_IMPLEMENTATION) || \
+ !defined(OMNI_MUTEX_LOCK_IMPLEMENTATION) || \
+ !defined(OMNI_MUTEX_TRYLOCK_IMPLEMENTATION)|| \
+ !defined(OMNI_MUTEX_UNLOCK_IMPLEMENTATION) || \
+ !defined(OMNI_CONDITION_IMPLEMENTATION) || \
+ !defined(OMNI_SEMAPHORE_IMPLEMENTATION) || \
+ !defined(OMNI_THREAD_IMPLEMENTATION))
+#error "Implementation header file incomplete"
+#endif
+
+
+//
+// This exception is thrown in the event of a fatal error.
+//
+
+class _OMNITHREAD_NTDLL_ omni_thread_fatal {
+public:
+ int error;
+ omni_thread_fatal(int e = 0) : error(e) {}
+};
+
+
+//
+// This exception is thrown when an operation is invoked with invalid
+// arguments.
+//
+
+class _OMNITHREAD_NTDLL_ omni_thread_invalid {};
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Mutex
+//
+///////////////////////////////////////////////////////////////////////////
+
+class _OMNITHREAD_NTDLL_ omni_mutex {
+
+public:
+ omni_mutex(void);
+ ~omni_mutex(void);
+
+ inline void lock(void) { OMNI_MUTEX_LOCK_IMPLEMENTATION }
+ inline void unlock(void) { OMNI_MUTEX_UNLOCK_IMPLEMENTATION }
+ inline int trylock(void) { return OMNI_MUTEX_TRYLOCK_IMPLEMENTATION }
+ // if mutex is unlocked, lock it and return 1 (true).
+ // If it's already locked then return 0 (false).
+
+ inline void acquire(void) { lock(); }
+ inline void release(void) { unlock(); }
+ // the names lock and unlock are preferred over acquire and release
+ // since we are attempting to be as POSIX-like as possible.
+
+ friend class omni_condition;
+
+private:
+ // dummy copy constructor and operator= to prevent copying
+ omni_mutex(const omni_mutex&);
+ omni_mutex& operator=(const omni_mutex&);
+
+OMNI_THREAD_EXPOSE:
+ OMNI_MUTEX_IMPLEMENTATION
+};
+
+//
+// As an alternative to:
+// {
+// mutex.lock();
+// .....
+// mutex.unlock();
+// }
+//
+// you can use a single instance of the omni_mutex_lock class:
+//
+// {
+// omni_mutex_lock l(mutex);
+// ....
+// }
+//
+// This has the advantage that mutex.unlock() will be called automatically
+// when an exception is thrown.
+//
+
+class _OMNITHREAD_NTDLL_ omni_mutex_lock {
+ omni_mutex& mutex;
+public:
+ omni_mutex_lock(omni_mutex& m) : mutex(m) { mutex.lock(); }
+ ~omni_mutex_lock(void) { mutex.unlock(); }
+private:
+ // dummy copy constructor and operator= to prevent copying
+ omni_mutex_lock(const omni_mutex_lock&);
+ omni_mutex_lock& operator=(const omni_mutex_lock&);
+};
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Condition variable
+//
+///////////////////////////////////////////////////////////////////////////
+
+class _OMNITHREAD_NTDLL_ omni_condition {
+
+ omni_mutex* mutex;
+
+public:
+ omni_condition(omni_mutex* m);
+ // constructor must be given a pointer to an existing mutex. The
+ // condition variable is then linked to the mutex, so that there is an
+ // implicit unlock and lock around wait() and timed_wait().
+
+ ~omni_condition(void);
+
+ void wait(void);
+ // wait for the condition variable to be signalled. The mutex is
+ // implicitly released before waiting and locked again after waking up.
+ // If wait() is called by multiple threads, a signal may wake up more
+ // than one thread. See POSIX threads documentation for details.
+
+ int timedwait(unsigned long secs, unsigned long nanosecs = 0);
+ // timedwait() is given an absolute time to wait until. To wait for a
+ // relative time from now, use omni_thread::get_time. See POSIX threads
+ // documentation for why absolute times are better than relative.
+ // Returns 1 (true) if successfully signalled, 0 (false) if time
+ // expired.
+
+ void signal(void);
+ // if one or more threads have called wait(), signal wakes up at least
+ // one of them, possibly more. See POSIX threads documentation for
+ // details.
+
+ void broadcast(void);
+ // broadcast is like signal but wakes all threads which have called
+ // wait().
+
+private:
+ // dummy copy constructor and operator= to prevent copying
+ omni_condition(const omni_condition&);
+ omni_condition& operator=(const omni_condition&);
+
+OMNI_THREAD_EXPOSE:
+ OMNI_CONDITION_IMPLEMENTATION
+};
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Counting (or binary) semaphore
+//
+///////////////////////////////////////////////////////////////////////////
+
+class _OMNITHREAD_NTDLL_ omni_semaphore {
+
+public:
+ // if max_count == 1, you've got a binary semaphore.
+ omni_semaphore(unsigned int initial = 1, unsigned int max_count = 0x7fffffff);
+ ~omni_semaphore(void);
+
+ void wait(void);
+ // if semaphore value is > 0 then decrement it and carry on. If it's
+ // already 0 then block.
+
+ int trywait(void);
+ // if semaphore value is > 0 then decrement it and return 1 (true).
+ // If it's already 0 then return 0 (false).
+
+ void post(void);
+ // if any threads are blocked in wait(), wake one of them up. Otherwise
+ // increment the value of the semaphore.
+
+private:
+ // dummy copy constructor and operator= to prevent copying
+ omni_semaphore(const omni_semaphore&);
+ omni_semaphore& operator=(const omni_semaphore&);
+
+OMNI_THREAD_EXPOSE:
+ OMNI_SEMAPHORE_IMPLEMENTATION
+};
+
+//
+// A helper class for semaphores, similar to omni_mutex_lock above.
+//
+
+class _OMNITHREAD_NTDLL_ omni_semaphore_lock {
+ omni_semaphore& sem;
+public:
+ omni_semaphore_lock(omni_semaphore& s) : sem(s) { sem.wait(); }
+ ~omni_semaphore_lock(void) { sem.post(); }
+private:
+ // dummy copy constructor and operator= to prevent copying
+ omni_semaphore_lock(const omni_semaphore_lock&);
+ omni_semaphore_lock& operator=(const omni_semaphore_lock&);
+};
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Thread
+//
+///////////////////////////////////////////////////////////////////////////
+
+class _OMNITHREAD_NTDLL_ omni_thread {
+
+public:
+
+ enum priority_t {
+ PRIORITY_LOW,
+ PRIORITY_NORMAL,
+ PRIORITY_HIGH
+ };
+
+ enum state_t {
+ STATE_NEW, // thread object exists but thread hasn't
+ // started yet.
+ STATE_RUNNING, // thread is running.
+ STATE_TERMINATED // thread has terminated but storage has not
+ // been reclaimed (i.e. waiting to be joined).
+ };
+
+ //
+ // Constructors set up the thread object but the thread won't start until
+ // start() is called. The create method can be used to construct and start
+ // a thread in a single call.
+ //
+
+ omni_thread(void (*fn)(void*), void* arg = NULL,
+ priority_t pri = PRIORITY_NORMAL);
+ omni_thread(void* (*fn)(void*), void* arg = NULL,
+ priority_t pri = PRIORITY_NORMAL);
+ // these constructors create a thread which will run the given function
+ // when start() is called. The thread will be detached if given a
+ // function with void return type, undetached if given a function
+ // returning void*. If a thread is detached, storage for the thread is
+ // reclaimed automatically on termination. Only an undetached thread
+ // can be joined.
+
+ void start(void);
+ // start() causes a thread created with one of the constructors to
+ // start executing the appropriate function.
+
+protected:
+
+ omni_thread(void* arg = NULL, priority_t pri = PRIORITY_NORMAL);
+ // this constructor is used in a derived class. The thread will
+ // execute the run() or run_undetached() member functions depending on
+ // whether start() or start_undetached() is called respectively.
+
+ void start_undetached(void);
+ // can be used with the above constructor in a derived class to cause
+ // the thread to be undetached. In this case the thread executes the
+ // run_undetached member function.
+
+ virtual ~omni_thread(void);
+ // destructor cannot be called by user (except via a derived class).
+ // Use exit() or cancel() instead. This also means a thread object must
+ // be allocated with new - it cannot be statically or automatically
+ // allocated. The destructor of a class that inherits from omni_thread
+ // shouldn't be public either (otherwise the thread object can be
+ // destroyed while the underlying thread is still running).
+
+public:
+
+ void join(void**);
+ // join causes the calling thread to wait for another's completion,
+ // putting the return value in the variable of type void* whose address
+ // is given (unless passed a null pointer). Only undetached threads
+ // may be joined. Storage for the thread will be reclaimed.
+
+ void set_priority(priority_t);
+ // set the priority of the thread.
+
+ static omni_thread* create(void (*fn)(void*), void* arg = NULL,
+ priority_t pri = PRIORITY_NORMAL);
+ static omni_thread* create(void* (*fn)(void*), void* arg = NULL,
+ priority_t pri = PRIORITY_NORMAL);
+ // create spawns a new thread executing the given function with the
+ // given argument at the given priority. Returns a pointer to the
+ // thread object. It simply constructs a new thread object then calls
+ // start.
+
+ static void exit(void* return_value = NULL);
+ // causes the calling thread to terminate.
+
+ static omni_thread* self(void);
+ // returns the calling thread's omni_thread object. If the
+ // calling thread is not the main thread and is not created
+ // using this library, returns 0. (But see create_dummy()
+ // below.)
+
+ static void yield(void);
+ // allows another thread to run.
+
+ static void sleep(unsigned long secs, unsigned long nanosecs = 0);
+ // sleeps for the given time.
+
+ static void get_time(unsigned long* abs_sec, unsigned long* abs_nsec,
+ unsigned long rel_sec = 0, unsigned long rel_nsec=0);
+ // calculates an absolute time in seconds and nanoseconds, suitable for
+ // use in timed_waits on condition variables, which is the current time
+ // plus the given relative offset.
+
+
+ static void stacksize(unsigned long sz);
+ static unsigned long stacksize();
+ // Use this value as the stack size when spawning a new thread.
+ // The default value (0) means that the thread library default is
+ // to be used.
+
+
+ // Per-thread data
+ //
+ // These functions allow you to attach additional data to an
+ // omni_thread. First allocate a key for yourself with
+ // allocate_key(). Then you can store any object whose class is
+ // derived from value_t. Any values still stored in the
+ // omni_thread when the thread exits are deleted.
+ //
+ // These functions are NOT thread safe, so you should be very
+ // careful about setting/getting data in a different thread to the
+ // current thread.
+
+ typedef unsigned int key_t;
+ static key_t allocate_key();
+
+ class value_t {
+ public:
+ virtual ~value_t() {}
+ };
+
+ value_t* set_value(key_t k, value_t* v);
+ // Sets a value associated with the given key. The key must
+ // have been allocated with allocate_key(). If a value has
+ // already been set with the specified key, the old value_t
+ // object is deleted and replaced. Returns the value which was
+ // set, or zero if the key is invalid.
+
+ value_t* get_value(key_t k);
+ // Returns the value associated with the key. If the key is
+ // invalid, or there is no value for the key, returns zero.
+
+ value_t* remove_value(key_t k);
+ // Removes the value associated with the key and returns it.
+ // If the key is invalid, or there is no value for the key,
+ // returns zero.
+
+
+ // Dummy omni_thread
+ //
+ // Sometimes, an application finds itself with threads created
+ // outside of omnithread which must interact with omnithread
+ // features such as the per-thread data. In this situation,
+ // omni_thread::self() would normally return 0. These functions
+ // allow the application to create a suitable dummy omni_thread
+ // object.
+
+ static omni_thread* create_dummy(void);
+ // creates a dummy omni_thread for the calling thread. Future
+ // calls to self() will return the dummy omni_thread. Throws
+ // omni_thread_invalid if this thread already has an
+ // associated omni_thread (real or dummy).
+
+ static void release_dummy();
+ // release the dummy omni_thread for this thread. This
+ // function MUST be called before the thread exits. Throws
+ // omni_thread_invalid if the calling thread does not have a
+ // dummy omni_thread.
+
+ // class ensure_self should be created on the stack. If created in
+ // a thread without an associated omni_thread, it creates a dummy
+ // thread which is released when the ensure_self object is deleted.
+
+ class ensure_self {
+ public:
+ inline ensure_self() : _dummy(0)
+ {
+ _self = omni_thread::self();
+ if (!_self) {
+ _dummy = 1;
+ _self = omni_thread::create_dummy();
+ }
+ }
+ inline ~ensure_self()
+ {
+ if (_dummy)
+ omni_thread::release_dummy();
+ }
+ inline omni_thread* self() { return _self; }
+ private:
+ omni_thread* _self;
+ int _dummy;
+ };
+
+
+private:
+
+ virtual void run(void* /*arg*/) {}
+ virtual void* run_undetached(void* /*arg*/) { return NULL; }
+ // can be overridden in a derived class. When constructed using the
+ // the constructor omni_thread(void*, priority_t), these functions are
+ // called by start() and start_undetached() respectively.
+
+ void common_constructor(void* arg, priority_t pri, int det);
+ // implements the common parts of the constructors.
+
+ omni_mutex mutex;
+ // used to protect any members which can change after construction,
+ // i.e. the following 2 members.
+
+ state_t _state;
+ priority_t _priority;
+
+ static omni_mutex* next_id_mutex;
+ static int next_id;
+ int _id;
+
+ void (*fn_void)(void*);
+ void* (*fn_ret)(void*);
+ void* thread_arg;
+ int detached;
+ int _dummy;
+ value_t** _values;
+ unsigned long _value_alloc;
+
+ omni_thread(const omni_thread&);
+ omni_thread& operator=(const omni_thread&);
+ // Not implemented
+
+public:
+
+ priority_t priority(void) {
+
+ // return this thread's priority.
+
+ omni_mutex_lock l(mutex);
+ return _priority;
+ }
+
+ state_t state(void) {
+
+ // return thread state (invalid, new, running or terminated).
+
+ omni_mutex_lock l(mutex);
+ return _state;
+ }
+
+ int id(void) { return _id; }
+ // return unique thread id within the current process.
+
+
+ // This class plus the instance of it declared below allows us to execute
+ // some initialisation code before main() is called.
+
+ class _OMNITHREAD_NTDLL_ init_t {
+ public:
+ init_t(void);
+ ~init_t(void);
+ };
+
+ friend class init_t;
+ friend class omni_thread_dummy;
+
+OMNI_THREAD_EXPOSE:
+ OMNI_THREAD_IMPLEMENTATION
+};
+
+#ifndef __rtems__
+static omni_thread::init_t omni_thread_init;
+#else
+// RTEMS calls global Ctor/Dtor in a context that is not
+// a posix thread. Calls to functions to pthread_self() in
+// that context returns NULL.
+// So, for RTEMS we will make the thread initialization at the
+// beginning of the Init task that has a posix context.
+#endif
+
+#endif
diff --git a/gnuradio-core/src/lib/omnithread/ot_VxThread.h b/gnuradio-core/src/lib/omnithread/ot_VxThread.h
new file mode 100644
index 0000000000..e96c036cce
--- /dev/null
+++ b/gnuradio-core/src/lib/omnithread/ot_VxThread.h
@@ -0,0 +1,118 @@
+#ifndef __VXTHREAD_H__
+#define __VXTHREAD_H__
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Project: omniORB
+%% Filename: $Filename$
+%% Author: Guillaume/Bill ARRECKX
+%% Copyright Wavetek Wandel & Goltermann, Plymouth.
+%% Description: OMNI thread implementation classes for VxWorks threads
+%% Notes:
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% $Log$
+%% Revision 1.1 2004/04/10 18:00:52 eb
+%% Initial revision
+%%
+%% Revision 1.1.1.1 2004/03/01 00:20:27 eb
+%% initial checkin
+%%
+%% Revision 1.1 2003/05/25 05:29:04 eb
+%% see ChangeLog
+%%
+%% Revision 1.1.2.1 2003/02/17 02:03:07 dgrisby
+%% vxWorks port. (Thanks Michael Sturm / Acterna Eningen GmbH).
+%%
+%% Revision 1.1.1.1 2002/11/19 14:55:21 sokcevti
+%% OmniOrb4.0.0 VxWorks port
+%%
+%% Revision 1.2 2002/06/14 12:45:50 engeln
+%% unnecessary members in condition removed.
+%% ---
+%%
+%% Revision 1.1.1.1 2002/04/02 10:08:49 sokcevti
+%% omniORB4 initial realease
+%%
+%% Revision 1.1 2001/03/23 16:50:23 hartmut
+%% Initial Version 2.8
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+*/
+
+
+///////////////////////////////////////////////////////////////////////////
+// Includes
+///////////////////////////////////////////////////////////////////////////
+#include <vxWorks.h>
+#include <semLib.h>
+#include <taskLib.h>
+
+
+///////////////////////////////////////////////////////////////////////////
+// Externs prototypes
+///////////////////////////////////////////////////////////////////////////
+extern "C" void omni_thread_wrapper(void* ptr);
+
+
+///////////////////////////////////////////////////////////////////////////
+// Exported macros
+// Note: These are added as private members in each class implementation.
+///////////////////////////////////////////////////////////////////////////
+#define OMNI_MUTEX_IMPLEMENTATION \
+ SEM_ID mutexID; \
+ bool m_bConstructed;
+
+#define OMNI_CONDITION_IMPLEMENTATION \
+ long waiters_; \
+ SEM_ID waiters_lock_; \
+ SEM_ID sema_;
+
+#define OMNI_SEMAPHORE_IMPLEMENTATION \
+ SEM_ID semID;
+
+#define OMNI_MUTEX_LOCK_IMPLEMENTATION \
+ if(semTake(mutexID, WAIT_FOREVER) != OK) \
+ { \
+ throw omni_thread_fatal(errno); \
+ }
+
+#define OMNI_MUTEX_UNLOCK_IMPLEMENTATION \
+ if(semGive(mutexID) != OK) \
+ { \
+ throw omni_thread_fatal(errno); \
+ }
+
+#define OMNI_THREAD_IMPLEMENTATION \
+ friend void omni_thread_wrapper(void* ptr); \
+ static int vxworks_priority(priority_t); \
+ omni_condition *running_cond; \
+ void* return_val; \
+ int tid; \
+ public: \
+ static void attach(void); \
+ static void detach(void); \
+ static void show(void);
+
+
+///////////////////////////////////////////////////////////////////////////
+// Porting macros
+///////////////////////////////////////////////////////////////////////////
+// This is a wrapper function for the 'main' function which does not exists
+// as such in VxWorks. The wrapper creates a launch function instead,
+// which spawns the application wrapped in a omni_thread.
+// Argc will always be null.
+///////////////////////////////////////////////////////////////////////////
+#define main( discarded_argc, discarded_argv ) \
+ omni_discard_retval() \
+ { \
+ throw; \
+ } \
+ int omni_main( int argc, char **argv ); \
+ void launch( ) \
+ { \
+ omni_thread* th = new omni_thread( (void(*)(void*))omni_main );\
+ th->start();\
+ }\
+ int omni_main( int argc, char **argv )
+
+
+#endif // ndef __VXTHREAD_H__
diff --git a/gnuradio-core/src/lib/omnithread/ot_mach.h b/gnuradio-core/src/lib/omnithread/ot_mach.h
new file mode 100644
index 0000000000..483f600fe9
--- /dev/null
+++ b/gnuradio-core/src/lib/omnithread/ot_mach.h
@@ -0,0 +1,51 @@
+// Package : omnithread
+// omnithread/posix.h Created : 7/97 lars immisch lars@ibp.de
+//
+// Copyright (C) 1994,1995,1996, 1997 Immisch, becker & Partner
+//
+// This file is part of the omnithread library
+//
+// The omnithread library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA
+//
+//
+// OMNI thread implementation classes for posix threads
+//
+
+#ifndef __omnithread_mach_h_
+#define __omnithread_mach_h_
+
+#include <mach/cthreads.h>
+
+extern "C" void* omni_thread_wrapper(void* ptr);
+
+#define OMNI_MUTEX_IMPLEMENTATION \
+ struct mutex mach_mutex;
+
+#define OMNI_CONDITION_IMPLEMENTATION \
+ struct condition mach_cond;
+
+#define OMNI_SEMAPHORE_IMPLEMENTATION \
+ omni_mutex m; \
+ omni_condition c; \
+ int value;
+
+
+#define OMNI_THREAD_IMPLEMENTATION \
+ cthread_t mach_thread; \
+ static int mach_priority(priority_t); \
+ friend void* omni_thread_wrapper(void* ptr);
+
+#endif
diff --git a/gnuradio-core/src/lib/omnithread/ot_nt.h b/gnuradio-core/src/lib/omnithread/ot_nt.h
new file mode 100644
index 0000000000..3ed173f29b
--- /dev/null
+++ b/gnuradio-core/src/lib/omnithread/ot_nt.h
@@ -0,0 +1,85 @@
+// Package : omnithread
+// omnithread/nt.h Created : 6/95 tjr
+//
+// Copyright (C) 1995, 1996, 1997 Olivetti & Oracle Research Laboratory
+//
+// This file is part of the omnithread library
+//
+// The omnithread library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA
+//
+//
+// OMNI thread implementation classes for NT threads.
+//
+
+#ifndef __omnithread_nt_h_
+#define __omnithread_nt_h_
+
+#ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# define OMNI_DEFINED_WIN32_LEAN_AND_MEAN
+#endif
+
+#include <windows.h>
+
+#ifdef OMNI_DEFINED_WIN32_LEAN_AND_MEAN
+# undef WIN32_LEAN_AND_MEAN
+# undef OMNI_DEFINED_WIN32_LEAN_AND_MEAN
+#endif
+
+
+#ifndef __BCPLUSPLUS__
+#define OMNI_THREAD_WRAPPER \
+ unsigned __stdcall omni_thread_wrapper(LPVOID ptr);
+#else
+#define OMNI_THREAD_WRAPPER \
+ void _USERENTRY omni_thread_wrapper(void *ptr);
+#endif
+
+extern "C" OMNI_THREAD_WRAPPER;
+
+#define OMNI_MUTEX_IMPLEMENTATION \
+ CRITICAL_SECTION crit;
+
+#define OMNI_MUTEX_LOCK_IMPLEMENTATION \
+ EnterCriticalSection(&crit);
+
+#define OMNI_MUTEX_TRYLOCK_IMPLEMENTATION \
+ TryEnterCriticalSection(&crit);
+
+#define OMNI_MUTEX_UNLOCK_IMPLEMENTATION \
+ LeaveCriticalSection(&crit);
+
+#define OMNI_CONDITION_IMPLEMENTATION \
+ CRITICAL_SECTION crit; \
+ omni_thread* waiting_head; \
+ omni_thread* waiting_tail;
+
+#define OMNI_SEMAPHORE_IMPLEMENTATION \
+ HANDLE nt_sem;
+
+#define OMNI_THREAD_IMPLEMENTATION \
+ HANDLE handle; \
+ DWORD nt_id; \
+ void* return_val; \
+ HANDLE cond_semaphore; \
+ omni_thread* cond_next; \
+ omni_thread* cond_prev; \
+ BOOL cond_waiting; \
+ static int nt_priority(priority_t); \
+ friend class omni_condition; \
+ friend OMNI_THREAD_WRAPPER;
+
+#endif
diff --git a/gnuradio-core/src/lib/omnithread/ot_posix.h b/gnuradio-core/src/lib/omnithread/ot_posix.h
new file mode 100644
index 0000000000..1e5bf9d294
--- /dev/null
+++ b/gnuradio-core/src/lib/omnithread/ot_posix.h
@@ -0,0 +1,81 @@
+// Package : omnithread
+// omnithread/posix.h Created : 7/94 tjr
+//
+// Copyright (C) 2006 Free Software Foundation, Inc.
+// Copyright (C) 1994,1995,1996, 1997 Olivetti & Oracle Research Laboratory
+//
+// This file is part of the omnithread library
+//
+// The omnithread library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA
+//
+//
+// OMNI thread implementation classes for posix threads
+//
+
+#ifndef __omnithread_posix_h_
+#define __omnithread_posix_h_
+
+#if defined(__alpha__) && defined(__osf1__) || defined(__hpux__)
+// stop unnecessary definitions of TRY, etc on OSF
+#ifndef EXC_HANDLING
+#define EXC_HANDLING
+#endif
+#endif
+
+#ifndef __POSIX_NT__
+# include <pthread.h>
+#else
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# define OMNI_DEFINED_WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
+# include "pthread_nt.h"
+# ifdef OMNI_DEFINED_WIN32_LEAN_AND_MEAN
+# undef WIN32_LEAN_AND_MEAN
+# undef OMNI_DEFINED_WIN32_LEAN_AND_MEAN
+# endif
+#endif
+
+extern "C" void* omni_thread_wrapper(void* ptr);
+
+#define OMNI_MUTEX_IMPLEMENTATION \
+ pthread_mutex_t posix_mutex;
+
+#define OMNI_MUTEX_LOCK_IMPLEMENTATION \
+ pthread_mutex_lock(&posix_mutex);
+
+#define OMNI_MUTEX_TRYLOCK_IMPLEMENTATION \
+ (pthread_mutex_trylock(&posix_mutex)==0);
+
+#define OMNI_MUTEX_UNLOCK_IMPLEMENTATION \
+ pthread_mutex_unlock(&posix_mutex);
+
+#define OMNI_CONDITION_IMPLEMENTATION \
+ pthread_cond_t posix_cond;
+
+#define OMNI_SEMAPHORE_IMPLEMENTATION \
+ omni_mutex m; \
+ omni_condition c; \
+ int value; \
+ int max_count;
+
+#define OMNI_THREAD_IMPLEMENTATION \
+ pthread_t posix_thread; \
+ static int posix_priority(priority_t); \
+ friend void* omni_thread_wrapper(void* ptr);
+
+#endif
diff --git a/gnuradio-core/src/lib/omnithread/ot_pthread_nt.h b/gnuradio-core/src/lib/omnithread/ot_pthread_nt.h
new file mode 100644
index 0000000000..cf3d879427
--- /dev/null
+++ b/gnuradio-core/src/lib/omnithread/ot_pthread_nt.h
@@ -0,0 +1,186 @@
+/* Package : omnithread
+ omnithread/pthread_nt.h Created : Steven Brenneis <brennes1@rjrt.com>
+
+ Copyright (C) 1998 Steven Brennes
+
+ This file is part of the omnithread library
+
+ The omnithread library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA
+
+ Posix Threads implementation for Windows NT, version 4.0
+*/
+
+#ifndef PTHREAD_NT_H_INCLUDED
+#define PTHREAD_NT_H_INCLUDED
+
+#include <errno.h>
+
+#ifndef ETIMEDOUT
+// May have to be changed if NT starts supporting more errno values
+#define ETIMEDOUT 60
+#endif
+
+#undef PthreadDraftVersion
+#define PthreadDraftVersion 10
+
+#define NoNanoSleep
+
+#define PthreadSupportThreadPriority
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _TIMERS_T_
+#define _TIMERS_T_
+ typedef struct timespec {
+ unsigned long tv_sec;
+ long tv_nsec;
+ } timespec_t;
+#endif
+
+typedef char* __pthreadLongString_t;
+typedef void* __pthreadLongAddr_t;
+typedef __pthreadLongAddr_t* __pthreadLongAddr_p;
+typedef long __pthreadLongInt_t;
+typedef unsigned long __pthreadLongUint_t;
+typedef __pthreadLongAddr_p __pthreadTsd_t;
+
+typedef struct __pthread_mutex_t {
+ unsigned int lock; /* LOCK, SLOW, TYPE, RECURSIVE */
+ unsigned int valid; /* Validation info */
+ __pthreadLongString_t name; /* Name of mutex */
+ unsigned int arg; /* printf argument for name */
+ unsigned int depth; /* Recursive lock depth */
+ unsigned long sequence; /* Mutex sequence number */
+ unsigned long owner; /* Current owner (if known */
+ __pthreadLongAddr_t block; /* Pointer to blocking struct */
+} pthread_mutex_t;
+
+typedef struct __pthread_mutexattr_t {
+ long valid;
+ __pthreadLongUint_t reserved[15];
+} pthread_mutexattr_t;
+
+typedef struct __pthread_cond_t {
+ unsigned int state; /* EVENT, SLOW, REFCNT */
+ unsigned int valid; /* Validation info */
+ __pthreadLongString_t name; /* Name of condition variable */
+ unsigned int arg; /* printf argument for name */
+ unsigned long sequence; /* Condition variable seq # */
+ __pthreadLongAddr_t block; /* Pointer to blocking struct */
+} pthread_cond_t ;
+
+typedef struct __pthread_condattr_t {
+ long valid;
+ __pthreadLongUint_t reserved[13];
+} pthread_condattr_t ;
+
+typedef struct __pthread_transp_t {
+ __pthreadLongAddr_t reserved1; /* Reserved to posix_nt */
+ __pthreadLongAddr_t reserved2; /* Reserved to posix_nt */
+ unsigned short size; /* Size of data structure */
+ unsigned char reserved3[2]; /* Reserved to posix_nt */
+ __pthreadLongAddr_t reserved4; /* Reserved to posix_nt */
+ __pthreadLongUint_t sequence; /* Thread sequence number */
+ __pthreadLongUint_t reserved5[2]; /* Reserved to posix_nt */
+ __pthreadLongAddr_t per_kt_area; /* Pointer to kernel context */
+ __pthreadLongAddr_t stack_base; /* Current stack base */
+ __pthreadLongAddr_t stack_reserve; /* Current stack reserve zone */
+ __pthreadLongAddr_t stack_yellow; /* Current stack yellow zone */
+ __pthreadLongAddr_t stack_guard; /* Current stack guard zone */
+ __pthreadLongUint_t stack_size; /* Size of stack */
+ __pthreadTsd_t tsd_values; /* TSD array (indexed by key) */
+ unsigned long tsd_count; /* Number of TSD cells */
+ __pthreadLongAddr_t reserved6; /* Reserved to posix_nt */
+ __pthreadLongAddr_t reserved7; /* Reserved to posix_nt */
+ unsigned int thread_flags; /* Dynamic external state */
+} pthread_transp_t, *pthread_transp_p;
+
+typedef pthread_transp_p pthread_t;
+
+typedef struct __pthread_attr_t {
+ long valid;
+ __pthreadLongString_t name;
+ __pthreadLongUint_t arg;
+ __pthreadLongUint_t reserved[19];
+} pthread_attr_t ;
+
+typedef unsigned int pthread_key_t;
+
+typedef struct sched_param {
+ int sched_priority;
+} sched_param_t;
+
+/* Function Prototypes */
+
+int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine)(void*), void *arg);
+int pthread_detach(pthread_t thread);
+int pthread_join(pthread_t thread, void **value_ptr);
+void pthread_exit(void *value_ptr);
+int pthread_attr_init(pthread_attr_t *attr);
+int pthread_attr_destroy(pthread_attr_t *attr);
+int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
+int pthread_attr_getstacksize(const pthread_attr_t *attr,
+ size_t *stacksize);
+int pthread_cond_init(pthread_cond_t *cond,
+ const pthread_condattr_t *attr);
+int pthread_cond_destroy(pthread_cond_t *cond);
+int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
+int pthread_cond_timedwait(pthread_cond_t *cond,
+ pthread_mutex_t *mutex,
+ const struct timespec *abstime);
+int pthread_cond_signal(pthread_cond_t *cond);
+int pthread_cond_broadcast(pthread_cond_t *cond);
+int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
+int pthread_key_delete(pthread_key_t key);
+int pthread_mutex_destroy(pthread_mutex_t *mutex);
+int pthread_mutex_init(pthread_mutex_t *mutex,
+ const pthread_mutexattr_t *attr);
+int pthread_mutex_lock(pthread_mutex_t *mutex);
+int pthread_mutex_trylock(pthread_mutex_t *mutex);
+int pthread_mutex_unlock(pthread_mutex_t *mutex);
+pthread_t pthread_self();
+int pthread_setspecific(pthread_key_t key, const void *value);
+void *pthread_getspecific(pthread_key_t key);
+int pthread_getschedparam(pthread_t thread, int *policy,
+ struct sched_param *param);
+int pthread_setschedparam(pthread_t thread, int policy,
+ const struct sched_param *param);
+int pthread_attr_setschedparam(pthread_attr_t *attr,
+ const struct sched_param *param);
+int pthread_attr_getschedparam(const pthread_attr_t *attr,
+ struct sched_param *param);
+
+int pthread_delay_np(const struct timespec *interval);
+int pthread_get_expiration_np(const struct timespec *delta,
+ struct timespec *abstime);
+
+# define SCHED_FIFO 1
+# define SCHED_RR 2
+# define SCHED_OTHER 3
+
+int sched_yield();
+int sched_get_priority_max(int policy);
+int sched_get_priority_min(int policy);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PTHREAD_NT_H_INCLUDED
diff --git a/gnuradio-core/src/lib/omnithread/ot_solaris.h b/gnuradio-core/src/lib/omnithread/ot_solaris.h
new file mode 100644
index 0000000000..aaef036f18
--- /dev/null
+++ b/gnuradio-core/src/lib/omnithread/ot_solaris.h
@@ -0,0 +1,47 @@
+// Package : omnithread
+// omnithread/solaris.h Created : 7/94 tjr
+//
+// Copyright (C) 1994,1995,1996, 1997 Olivetti & Oracle Research Laboratory
+//
+// This file is part of the omnithread library
+//
+// The omnithread library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA
+//
+// OMNI thread implementation classes for solaris threads.
+//
+
+#ifndef __omnithread_solaris_h_
+#define __omnithread_solaris_h_
+
+#include <thread.h>
+
+extern "C" void* omni_thread_wrapper(void* ptr);
+
+#define OMNI_MUTEX_IMPLEMENTATION \
+ mutex_t sol_mutex;
+
+#define OMNI_CONDITION_IMPLEMENTATION \
+ cond_t sol_cond;
+
+#define OMNI_SEMAPHORE_IMPLEMENTATION \
+ sema_t sol_sem;
+
+#define OMNI_THREAD_IMPLEMENTATION \
+ thread_t sol_thread; \
+ static int sol_priority(priority_t); \
+ friend void* omni_thread_wrapper(void* ptr);
+
+#endif
diff --git a/gnuradio-core/src/lib/omnithread/posix.cc b/gnuradio-core/src/lib/omnithread/posix.cc
new file mode 100644
index 0000000000..5fda14fcba
--- /dev/null
+++ b/gnuradio-core/src/lib/omnithread/posix.cc
@@ -0,0 +1,972 @@
+// Package : omnithread
+// omnithread/posix.cc Created : 7/94 tjr
+//
+// Copyright (C) 2006 Free Software Foundation, Inc.
+// Copyright (C) 1994-1999 AT&T Laboratories Cambridge
+//
+// This file is part of the omnithread library
+//
+// The omnithread library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA
+//
+
+//
+// Implementation of OMNI thread abstraction for posix threads
+//
+// The source below tests for the definition of the macros:
+// PthreadDraftVersion
+// PthreadSupportThreadPriority
+// NoNanoSleep
+// NeedPthreadInit
+//
+// As different draft versions of the pthread standard P1003.4a/P1003.1c
+// define slightly different APIs, the macro 'PthreadDraftVersion'
+// identifies the draft version supported by this particular platform.
+//
+// Some unix variants do not support thread priority unless a real-time
+// kernel option is installed. The macro 'PthreadSupportThreadPriority',
+// if defined, enables the use of thread priority. If it is not defined,
+// setting or changing thread priority will be silently ignored.
+//
+// nanosleep() is defined in Posix P1003.4 since Draft 9 (?).
+// Not all platforms support this standard. The macro 'NoNanoSleep'
+// identifies platform that don't.
+//
+
+#include <config.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <time.h>
+#include <omnithread.h>
+
+#ifdef HAVE_NANOSLEEP
+#undef NoNanoSleep
+#else
+#define NoNanoSleep
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+// typedef of struct timeval and gettimeofday();
+#include <sys/time.h>
+#include <unistd.h>
+#endif
+
+#if defined(__linux__) && defined(_MIT_POSIX_THREADS)
+#include <pthread/mit/sys/timers.h>
+#endif
+
+#if defined(__irix__) && defined(PthreadSupportThreadPriority)
+#if _POSIX_THREAD_PRIORITY_SCHEDULING
+#include <sched.h>
+#endif
+#endif
+
+#define DB(x) // x
+//#include <iostream.h> or #include <iostream> if DB is on.
+
+#if (PthreadDraftVersion <= 6)
+#define ERRNO(x) (((x) != 0) ? (errno) : 0)
+#ifdef __VMS
+// pthread_setprio returns old priority on success (draft version 4:
+// OpenVms version < 7)
+#define THROW_ERRORS(x) { if ((x) == -1) throw omni_thread_fatal(errno); }
+#else
+#define THROW_ERRORS(x) { if ((x) != 0) throw omni_thread_fatal(errno); }
+#endif
+#else
+#define ERRNO(x) (x)
+#define THROW_ERRORS(x) { int rc = (x); \
+ if (rc != 0) throw omni_thread_fatal(rc); }
+#endif
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Mutex
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_mutex::omni_mutex(void)
+{
+#if (PthreadDraftVersion == 4)
+ THROW_ERRORS(pthread_mutex_init(&posix_mutex, pthread_mutexattr_default));
+#else
+ THROW_ERRORS(pthread_mutex_init(&posix_mutex, 0));
+#endif
+}
+
+omni_mutex::~omni_mutex(void)
+{
+ THROW_ERRORS(pthread_mutex_destroy(&posix_mutex));
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Condition variable
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_condition::omni_condition(omni_mutex* m) : mutex(m)
+{
+#if (PthreadDraftVersion == 4)
+ THROW_ERRORS(pthread_cond_init(&posix_cond, pthread_condattr_default));
+#else
+ THROW_ERRORS(pthread_cond_init(&posix_cond, 0));
+#endif
+}
+
+omni_condition::~omni_condition(void)
+{
+ THROW_ERRORS(pthread_cond_destroy(&posix_cond));
+}
+
+void
+omni_condition::wait(void)
+{
+ THROW_ERRORS(pthread_cond_wait(&posix_cond, &mutex->posix_mutex));
+}
+
+int
+omni_condition::timedwait(unsigned long secs, unsigned long nanosecs)
+{
+ timespec rqts = { secs, nanosecs };
+
+again:
+ int rc = ERRNO(pthread_cond_timedwait(&posix_cond,
+ &mutex->posix_mutex, &rqts));
+ if (rc == 0)
+ return 1;
+
+#if (PthreadDraftVersion <= 6)
+ if (rc == EAGAIN)
+ return 0;
+#endif
+
+ // Some versions of unix produces this errno when the wait was
+ // interrupted by a unix signal or fork.
+ // Some versions of the glibc 2.0.x produces this errno when the
+ // program is debugged under gdb. Straightly speaking this is non-posix
+ // compliant. We catch this here to make debugging possible.
+ if (rc == EINTR)
+ goto again;
+
+ if (rc == ETIMEDOUT)
+ return 0;
+
+ throw omni_thread_fatal(rc);
+#ifdef _MSC_VER
+ return 0;
+#endif
+}
+
+void
+omni_condition::signal(void)
+{
+ THROW_ERRORS(pthread_cond_signal(&posix_cond));
+}
+
+void
+omni_condition::broadcast(void)
+{
+ THROW_ERRORS(pthread_cond_broadcast(&posix_cond));
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Counting (or binary) semaphore
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_semaphore::omni_semaphore(unsigned int initial, unsigned int _max_count) : c(&m)
+{
+ value = initial;
+ max_count = _max_count;
+ if (value < 0 || max_count < 1)
+ throw omni_thread_fatal(0);
+}
+
+omni_semaphore::~omni_semaphore(void)
+{
+}
+
+void
+omni_semaphore::wait(void)
+{
+ omni_mutex_lock l(m);
+
+ while (value == 0)
+ c.wait();
+
+ value--;
+}
+
+int
+omni_semaphore::trywait(void)
+{
+ omni_mutex_lock l(m);
+
+ if (value == 0)
+ return 0;
+
+ value--;
+ return 1;
+}
+
+void
+omni_semaphore::post(void)
+{
+ {
+ omni_mutex_lock l(m);
+ if (value < max_count)
+ value++;
+ }
+
+ c.signal();
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Thread
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//
+// static variables
+//
+
+omni_mutex* omni_thread::next_id_mutex;
+int omni_thread::next_id = 0;
+
+static pthread_key_t self_key;
+
+#ifdef PthreadSupportThreadPriority
+static int lowest_priority;
+static int normal_priority;
+static int highest_priority;
+#endif
+
+#if defined(__osf1__) && defined(__alpha__) || defined(__VMS)
+// omniORB requires a larger stack size than the default (21120) on OSF/1
+static size_t stack_size = 32768;
+#elif defined(__rtems__)
+static size_t stack_size = ThreadStackSize;
+#elif defined(__aix__)
+static size_t stack_size = 262144;
+#else
+static size_t stack_size = 0;
+#endif
+
+//
+// Initialisation function (gets called before any user code).
+//
+
+static int& count() {
+ static int the_count = 0;
+ return the_count;
+}
+
+omni_thread::init_t::init_t(void)
+{
+ if (count()++ != 0) // only do it once however many objects get created.
+ return;
+
+ DB(cerr << "omni_thread::init: posix 1003.4a/1003.1c (draft "
+ << PthreadDraftVersion << ") implementation initialising\n");
+
+#ifdef NeedPthreadInit
+
+ pthread_init();
+
+#endif
+
+#if (PthreadDraftVersion == 4)
+ THROW_ERRORS(pthread_keycreate(&self_key, NULL));
+#else
+ THROW_ERRORS(pthread_key_create(&self_key, NULL));
+#endif
+
+#ifdef PthreadSupportThreadPriority
+
+#if defined(__osf1__) && defined(__alpha__) || defined(__VMS)
+
+ lowest_priority = PRI_OTHER_MIN;
+ highest_priority = PRI_OTHER_MAX;
+
+#elif defined(__hpux__)
+
+ lowest_priority = PRI_OTHER_MIN;
+ highest_priority = PRI_OTHER_MAX;
+
+#elif defined(__sunos__) && (__OSVERSION__ == 5)
+
+ // a bug in pthread_attr_setschedparam means lowest priority is 1 not 0
+
+ lowest_priority = 1;
+ highest_priority = 3;
+
+#else
+
+ lowest_priority = sched_get_priority_min(SCHED_FIFO);
+ highest_priority = sched_get_priority_max(SCHED_FIFO);
+
+#endif
+
+ switch (highest_priority - lowest_priority) {
+
+ case 0:
+ case 1:
+ normal_priority = lowest_priority;
+ break;
+
+ default:
+ normal_priority = lowest_priority + 1;
+ break;
+ }
+
+#endif /* PthreadSupportThreadPriority */
+
+ next_id_mutex = new omni_mutex;
+
+ //
+ // Create object for this (i.e. initial) thread.
+ //
+
+ omni_thread* t = new omni_thread;
+
+ t->_state = STATE_RUNNING;
+
+ t->posix_thread = pthread_self ();
+
+ DB(cerr << "initial thread " << t->id() << endl);
+
+ THROW_ERRORS(pthread_setspecific(self_key, (void*)t));
+
+#ifdef PthreadSupportThreadPriority
+
+#if (PthreadDraftVersion == 4)
+
+ THROW_ERRORS(pthread_setprio(t->posix_thread,
+ posix_priority(PRIORITY_NORMAL)));
+
+#elif (PthreadDraftVersion == 6)
+
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+
+ THROW_ERRORS(pthread_attr_setprio(&attr, posix_priority(PRIORITY_NORMAL)));
+
+ THROW_ERRORS(pthread_setschedattr(t->posix_thread, attr));
+
+#else
+
+ struct sched_param sparam;
+
+ sparam.sched_priority = posix_priority(PRIORITY_NORMAL);
+
+ THROW_ERRORS(pthread_setschedparam(t->posix_thread, SCHED_OTHER, &sparam));
+
+#endif /* PthreadDraftVersion */
+
+#endif /* PthreadSupportThreadPriority */
+}
+
+omni_thread::init_t::~init_t(void)
+{
+ if (--count() != 0) return;
+
+ omni_thread* self = omni_thread::self();
+ if (!self) return;
+
+ pthread_setspecific(self_key, 0);
+ delete self;
+
+ delete next_id_mutex;
+}
+
+//
+// Wrapper for thread creation.
+//
+
+extern "C" void*
+omni_thread_wrapper(void* ptr)
+{
+ omni_thread* me = (omni_thread*)ptr;
+
+ DB(cerr << "omni_thread_wrapper: thread " << me->id()
+ << " started\n");
+
+ THROW_ERRORS(pthread_setspecific(self_key, me));
+
+ //
+ // Now invoke the thread function with the given argument.
+ //
+
+ if (me->fn_void != NULL) {
+ (*me->fn_void)(me->thread_arg);
+ omni_thread::exit();
+ }
+
+ if (me->fn_ret != NULL) {
+ void* return_value = (*me->fn_ret)(me->thread_arg);
+ omni_thread::exit(return_value);
+ }
+
+ if (me->detached) {
+ me->run(me->thread_arg);
+ omni_thread::exit();
+ } else {
+ void* return_value = me->run_undetached(me->thread_arg);
+ omni_thread::exit(return_value);
+ }
+
+ // should never get here.
+
+ return NULL;
+}
+
+
+//
+// Constructors for omni_thread - set up the thread object but don't
+// start it running.
+//
+
+// construct a detached thread running a given function.
+
+omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri)
+{
+ common_constructor(arg, pri, 1);
+ fn_void = fn;
+ fn_ret = NULL;
+}
+
+// construct an undetached thread running a given function.
+
+omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri)
+{
+ common_constructor(arg, pri, 0);
+ fn_void = NULL;
+ fn_ret = fn;
+}
+
+// construct a thread which will run either run() or run_undetached().
+
+omni_thread::omni_thread(void* arg, priority_t pri)
+{
+ common_constructor(arg, pri, 1);
+ fn_void = NULL;
+ fn_ret = NULL;
+}
+
+// common part of all constructors.
+
+void
+omni_thread::common_constructor(void* arg, priority_t pri, int det)
+{
+ _state = STATE_NEW;
+ _priority = pri;
+
+ next_id_mutex->lock();
+ _id = next_id++;
+ next_id_mutex->unlock();
+
+ thread_arg = arg;
+ detached = det; // may be altered in start_undetached()
+
+ _dummy = 0;
+ _values = 0;
+ _value_alloc = 0;
+ // posix_thread is set up in initialisation routine or start().
+}
+
+
+//
+// Destructor for omni_thread.
+//
+
+omni_thread::~omni_thread(void)
+{
+ DB(cerr << "destructor called for thread " << id() << endl);
+ if (_values) {
+ for (key_t i=0; i < _value_alloc; i++) {
+ if (_values[i]) {
+ delete _values[i];
+ }
+ }
+ delete [] _values;
+ }
+}
+
+
+//
+// Start the thread
+//
+
+void
+omni_thread::start(void)
+{
+ omni_mutex_lock l(mutex);
+
+ if (_state != STATE_NEW)
+ throw omni_thread_invalid();
+
+ pthread_attr_t attr;
+
+#if (PthreadDraftVersion == 4)
+ pthread_attr_create(&attr);
+#else
+ pthread_attr_init(&attr);
+#endif
+
+#if (PthreadDraftVersion == 8)
+ pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+#endif
+
+#ifdef PthreadSupportThreadPriority
+
+#if (PthreadDraftVersion <= 6)
+
+ THROW_ERRORS(pthread_attr_setprio(&attr, posix_priority(_priority)));
+
+#else
+
+ struct sched_param sparam;
+
+ sparam.sched_priority = posix_priority(_priority);
+
+ THROW_ERRORS(pthread_attr_setschedparam(&attr, &sparam));
+
+#endif /* PthreadDraftVersion */
+
+#endif /* PthreadSupportThreadPriority */
+
+#if !defined(__linux__)
+ if (stack_size) {
+ THROW_ERRORS(pthread_attr_setstacksize(&attr, stack_size));
+ }
+#endif
+
+
+#if (PthreadDraftVersion == 4)
+ THROW_ERRORS(pthread_create(&posix_thread, attr, omni_thread_wrapper,
+ (void*)this));
+ pthread_attr_delete(&attr);
+#else
+ THROW_ERRORS(pthread_create(&posix_thread, &attr, omni_thread_wrapper,
+ (void*)this));
+ pthread_attr_destroy(&attr);
+#endif
+
+ _state = STATE_RUNNING;
+
+ if (detached) {
+
+#if (PthreadDraftVersion <= 6)
+ THROW_ERRORS(pthread_detach(&posix_thread));
+#else
+ THROW_ERRORS(pthread_detach(posix_thread));
+#endif
+ }
+}
+
+
+//
+// Start a thread which will run the member function run_undetached().
+//
+
+void
+omni_thread::start_undetached(void)
+{
+ if ((fn_void != NULL) || (fn_ret != NULL))
+ throw omni_thread_invalid();
+
+ detached = 0;
+ start();
+}
+
+
+//
+// join - simply check error conditions & call pthread_join.
+//
+
+void
+omni_thread::join(void** status)
+{
+ mutex.lock();
+
+ if ((_state != STATE_RUNNING) && (_state != STATE_TERMINATED)) {
+ mutex.unlock();
+ throw omni_thread_invalid();
+ }
+
+ mutex.unlock();
+
+ if (this == self())
+ throw omni_thread_invalid();
+
+ if (detached)
+ throw omni_thread_invalid();
+
+ DB(cerr << "omni_thread::join: doing pthread_join\n");
+
+ THROW_ERRORS(pthread_join(posix_thread, status));
+
+ DB(cerr << "omni_thread::join: pthread_join succeeded\n");
+
+#if (PthreadDraftVersion == 4)
+ // With draft 4 pthreads implementations (HPUX 10.x and
+ // Digital Unix 3.2), have to detach the thread after
+ // join. If not, the storage for the thread will not be
+ // be reclaimed.
+ THROW_ERRORS(pthread_detach(&posix_thread));
+#endif
+
+ delete this;
+}
+
+
+//
+// Change this thread's priority.
+//
+
+void
+omni_thread::set_priority(priority_t pri)
+{
+ omni_mutex_lock l(mutex);
+
+ if (_state != STATE_RUNNING)
+ throw omni_thread_invalid();
+
+ _priority = pri;
+
+#ifdef PthreadSupportThreadPriority
+
+#if (PthreadDraftVersion == 4)
+
+ THROW_ERRORS(pthread_setprio(posix_thread, posix_priority(pri)));
+
+#elif (PthreadDraftVersion == 6)
+
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+
+ THROW_ERRORS(pthread_attr_setprio(&attr, posix_priority(pri)));
+
+ THROW_ERRORS(pthread_setschedattr(posix_thread, attr));
+
+#else
+
+ struct sched_param sparam;
+
+ sparam.sched_priority = posix_priority(pri);
+
+ THROW_ERRORS(pthread_setschedparam(posix_thread, SCHED_OTHER, &sparam));
+
+#endif /* PthreadDraftVersion */
+
+#endif /* PthreadSupportThreadPriority */
+}
+
+
+//
+// create - construct a new thread object and start it running. Returns thread
+// object if successful, null pointer if not.
+//
+
+// detached version
+
+omni_thread*
+omni_thread::create(void (*fn)(void*), void* arg, priority_t pri)
+{
+ omni_thread* t = new omni_thread(fn, arg, pri);
+
+ t->start();
+
+ return t;
+}
+
+// undetached version
+
+omni_thread*
+omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri)
+{
+ omni_thread* t = new omni_thread(fn, arg, pri);
+
+ t->start();
+
+ return t;
+}
+
+
+//
+// exit() _must_ lock the mutex even in the case of a detached thread. This is
+// because a thread may run to completion before the thread that created it has
+// had a chance to get out of start(). By locking the mutex we ensure that the
+// creating thread must have reached the end of start() before we delete the
+// thread object. Of course, once the call to start() returns, the user can
+// still incorrectly refer to the thread object, but that's their problem.
+//
+
+void
+omni_thread::exit(void* return_value)
+{
+ omni_thread* me = self();
+
+ if (me)
+ {
+ me->mutex.lock();
+
+ me->_state = STATE_TERMINATED;
+
+ me->mutex.unlock();
+
+ DB(cerr << "omni_thread::exit: thread " << me->id() << " detached "
+ << me->detached << " return value " << return_value << endl);
+
+ if (me->detached)
+ delete me;
+ }
+ else
+ {
+ DB(cerr << "omni_thread::exit: called with a non-omnithread. Exit quietly." << endl);
+ }
+
+ pthread_exit(return_value);
+}
+
+
+omni_thread*
+omni_thread::self(void)
+{
+ omni_thread* me;
+
+#if (PthreadDraftVersion <= 6)
+
+ THROW_ERRORS(pthread_getspecific(self_key, (void**)&me));
+
+#else
+
+ me = (omni_thread *)pthread_getspecific(self_key);
+
+#endif
+
+ if (!me) {
+ // This thread is not created by omni_thread::start because it
+ // doesn't has a class omni_thread instance attached to its key.
+ DB(cerr << "omni_thread::self: called with a non-omnithread. NULL is returned." << endl);
+ }
+
+ return me;
+}
+
+
+void
+omni_thread::yield(void)
+{
+#if (PthreadDraftVersion == 6)
+
+ pthread_yield(NULL);
+
+#elif (PthreadDraftVersion < 9)
+
+ pthread_yield();
+
+#else
+
+ THROW_ERRORS(sched_yield());
+
+#endif
+}
+
+
+void
+omni_thread::sleep(unsigned long secs, unsigned long nanosecs)
+{
+ timespec rqts = { secs, nanosecs };
+
+#ifndef NoNanoSleep
+
+ timespec remain;
+ while (nanosleep(&rqts, &remain)) {
+ if (errno == EINTR) {
+ rqts.tv_sec = remain.tv_sec;
+ rqts.tv_nsec = remain.tv_nsec;
+ continue;
+ }
+ else
+ throw omni_thread_fatal(errno);
+ }
+#else
+
+#if defined(__osf1__) && defined(__alpha__) || defined(__hpux__) && (__OSVERSION__ == 10) || defined(__VMS) || defined(__SINIX__) || defined (__POSIX_NT__)
+
+ if (pthread_delay_np(&rqts) != 0)
+ throw omni_thread_fatal(errno);
+
+#elif defined(__linux__) || defined(__aix__)
+
+ if (secs > 2000) {
+ while ((secs = ::sleep(secs))) ;
+ } else {
+ usleep(secs * 1000000 + (nanosecs / 1000));
+ }
+
+#elif defined(__darwin__) || defined(__macos__)
+
+ // Single UNIX Specification says argument of usleep() must be
+ // less than 1,000,000.
+ secs += nanosecs / 1000000000;
+ nanosecs %= 1000000000;
+ while ((secs = ::sleep(secs))) ;
+ usleep(nanosecs / 1000);
+
+#else
+
+ throw omni_thread_invalid();
+
+#endif
+#endif /* NoNanoSleep */
+}
+
+
+void
+omni_thread::get_time(unsigned long* abs_sec, unsigned long* abs_nsec,
+ unsigned long rel_sec, unsigned long rel_nsec)
+{
+ timespec abs;
+
+#if defined(__osf1__) && defined(__alpha__) || defined(__hpux__) && (__OSVERSION__ == 10) || defined(__VMS) || defined(__SINIX__) || defined(__POSIX_NT__)
+
+ timespec rel;
+ rel.tv_sec = rel_sec;
+ rel.tv_nsec = rel_nsec;
+ THROW_ERRORS(pthread_get_expiration_np(&rel, &abs));
+
+#else
+
+#ifdef HAVE_CLOCK_GETTIME /* __linux__ || __aix__ */
+
+ clock_gettime(CLOCK_REALTIME, &abs);
+
+#elif defined(HAVE_GETTIMEOFDAY) /* defined(__linux__) || defined(__aix__) || defined(__SCO_VERSION__) || defined(__darwin__) || defined(__macos__) */
+
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ abs.tv_sec = tv.tv_sec;
+ abs.tv_nsec = tv.tv_usec * 1000;
+
+#else
+#error no get time support
+#endif /* __linux__ || __aix__ */
+
+ abs.tv_nsec += rel_nsec;
+ abs.tv_sec += rel_sec + abs.tv_nsec / 1000000000;
+ abs.tv_nsec = abs.tv_nsec % 1000000000;
+
+#endif /* __osf1__ && __alpha__ */
+
+ *abs_sec = abs.tv_sec;
+ *abs_nsec = abs.tv_nsec;
+}
+
+
+int
+omni_thread::posix_priority(priority_t pri)
+{
+#ifdef PthreadSupportThreadPriority
+ switch (pri) {
+
+ case PRIORITY_LOW:
+ return lowest_priority;
+
+ case PRIORITY_NORMAL:
+ return normal_priority;
+
+ case PRIORITY_HIGH:
+ return highest_priority;
+
+ }
+#endif
+
+ throw omni_thread_invalid();
+#ifdef _MSC_VER
+ return 0;
+#endif
+}
+
+void
+omni_thread::stacksize(unsigned long sz)
+{
+ stack_size = sz;
+}
+
+unsigned long
+omni_thread::stacksize()
+{
+ return stack_size;
+}
+
+//
+// Dummy thread
+//
+
+class omni_thread_dummy : public omni_thread {
+public:
+ inline omni_thread_dummy() : omni_thread()
+ {
+ _dummy = 1;
+ _state = STATE_RUNNING;
+ posix_thread = pthread_self();
+ THROW_ERRORS(pthread_setspecific(self_key, (void*)this));
+ }
+ inline ~omni_thread_dummy()
+ {
+ THROW_ERRORS(pthread_setspecific(self_key, 0));
+ }
+};
+
+omni_thread*
+omni_thread::create_dummy()
+{
+ if (omni_thread::self())
+ throw omni_thread_invalid();
+
+ return new omni_thread_dummy;
+}
+
+void
+omni_thread::release_dummy()
+{
+ omni_thread* self = omni_thread::self();
+ if (!self || !self->_dummy)
+ throw omni_thread_invalid();
+
+ omni_thread_dummy* dummy = (omni_thread_dummy*)self;
+ delete dummy;
+}
+
+
+#define INSIDE_THREAD_IMPL_CC
+#include "threaddata.cc"
+#undef INSIDE_THREAD_IMPL_CC
diff --git a/gnuradio-core/src/lib/omnithread/solaris.cc b/gnuradio-core/src/lib/omnithread/solaris.cc
new file mode 100644
index 0000000000..827a645faf
--- /dev/null
+++ b/gnuradio-core/src/lib/omnithread/solaris.cc
@@ -0,0 +1,615 @@
+// Package : omnithread
+// omnithread/solaris.cc Created : 7/94 tjr
+//
+// Copyright (C) 1994-1999 AT&T Laboratories Cambridge
+//
+// This file is part of the omnithread library
+//
+// The omnithread library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA
+//
+//
+// Implementation of OMNI thread abstraction for solaris threads.
+//
+
+#include <stdlib.h>
+#include <errno.h>
+#include <omnithread.h>
+
+#define DB(x) // x
+// #include <iostream> or #include <iostream.h> if DB is on.
+
+#define THROW_ERRORS(x) { int rc = (x); \
+ if (rc != 0) throw omni_thread_fatal(rc); }
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Mutex
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_mutex::omni_mutex(void)
+{
+ THROW_ERRORS(mutex_init(&sol_mutex, USYNC_THREAD, 0));
+}
+
+omni_mutex::~omni_mutex(void)
+{
+ THROW_ERRORS(mutex_destroy(&sol_mutex));
+}
+
+void
+omni_mutex::lock(void)
+{
+ THROW_ERRORS(mutex_lock(&sol_mutex));
+}
+
+void
+omni_mutex::unlock(void)
+{
+ THROW_ERRORS(mutex_unlock(&sol_mutex));
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Condition variable
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_condition::omni_condition(omni_mutex* m) : mutex(m)
+{
+ THROW_ERRORS(cond_init(&sol_cond, USYNC_THREAD, 0));
+}
+
+omni_condition::~omni_condition(void)
+{
+ THROW_ERRORS(cond_destroy(&sol_cond));
+}
+
+void
+omni_condition::wait(void)
+{
+ THROW_ERRORS(cond_wait(&sol_cond, &mutex->sol_mutex));
+}
+
+int
+omni_condition::timedwait(unsigned long secs, unsigned long nanosecs)
+{
+ timespec rqts = { secs, nanosecs };
+
+ again:
+ int rc = cond_timedwait(&sol_cond, &mutex->sol_mutex, &rqts);
+
+ if (rc == 0)
+ return 1;
+
+ if (rc == EINTR)
+ goto again;
+
+ if (rc == ETIME)
+ return 0;
+
+ throw omni_thread_fatal(rc);
+}
+
+void
+omni_condition::signal(void)
+{
+ THROW_ERRORS(cond_signal(&sol_cond));
+}
+
+void
+omni_condition::broadcast(void)
+{
+ THROW_ERRORS(cond_broadcast(&sol_cond));
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Counting semaphore
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_semaphore::omni_semaphore(unsigned int initial)
+{
+ THROW_ERRORS(sema_init(&sol_sem, initial, USYNC_THREAD, NULL));
+}
+
+omni_semaphore::~omni_semaphore(void)
+{
+ THROW_ERRORS(sema_destroy(&sol_sem));
+}
+
+void
+omni_semaphore::wait(void)
+{
+ THROW_ERRORS(sema_wait(&sol_sem));
+}
+
+void
+omni_semaphore::post(void)
+{
+ THROW_ERRORS(sema_post(&sol_sem));
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Thread
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//
+// Static variables
+//
+
+int omni_thread::init_t::count = 0;
+
+omni_mutex* omni_thread::next_id_mutex;
+int omni_thread::next_id = 0;
+
+static thread_key_t self_key;
+
+static size_t stack_size = 0;
+
+//
+// Initialisation function (gets called before any user code).
+//
+
+omni_thread::init_t::init_t(void)
+{
+ if (count++ != 0) // only do it once however many objects get created.
+ return;
+
+ DB(cerr << "omni_thread::init: solaris implementation initialising\n");
+
+ THROW_ERRORS(thr_keycreate(&self_key, NULL));
+
+ next_id_mutex = new omni_mutex;
+
+ //
+ // Create object for this (i.e. initial) thread.
+ //
+
+ omni_thread* t = new omni_thread;
+
+ t->_state = STATE_RUNNING;
+
+ t->sol_thread = thr_self();
+
+ DB(cerr << "initial thread " << t->id() << " sol_thread " << t->sol_thread
+ << endl);
+
+ THROW_ERRORS(thr_setspecific(self_key, (void*)t));
+
+ THROW_ERRORS(thr_setprio(t->sol_thread, sol_priority(PRIORITY_NORMAL)));
+}
+
+
+//
+// Wrapper for thread creation.
+//
+
+extern "C" void*
+omni_thread_wrapper(void* ptr)
+{
+ omni_thread* me = (omni_thread*)ptr;
+
+ DB(cerr << "omni_thread::wrapper: thread " << me->id()
+ << " started\n");
+
+ THROW_ERRORS(thr_setspecific(self_key, me));
+
+ //
+ // Now invoke the thread function with the given argument.
+ //
+
+ if (me->fn_void != NULL) {
+ (*me->fn_void)(me->thread_arg);
+ omni_thread::exit();
+ }
+
+ if (me->fn_ret != NULL) {
+ void* return_value = (*me->fn_ret)(me->thread_arg);
+ omni_thread::exit(return_value);
+ }
+
+ if (me->detached) {
+ me->run(me->thread_arg);
+ omni_thread::exit();
+ } else {
+ void* return_value = me->run_undetached(me->thread_arg);
+ omni_thread::exit(return_value);
+ }
+
+ // should never get here.
+
+ return NULL;
+}
+
+
+//
+// Constructors for omni_thread - set up the thread object but don't
+// start it running.
+//
+
+// construct a detached thread running a given function.
+
+omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri)
+{
+ common_constructor(arg, pri, 1);
+ fn_void = fn;
+ fn_ret = NULL;
+}
+
+// construct an undetached thread running a given function.
+
+omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri)
+{
+ common_constructor(arg, pri, 0);
+ fn_void = NULL;
+ fn_ret = fn;
+}
+
+// construct a thread which will run either run() or run_undetached().
+
+omni_thread::omni_thread(void* arg, priority_t pri)
+{
+ common_constructor(arg, pri, 1);
+ fn_void = NULL;
+ fn_ret = NULL;
+}
+
+// common part of all constructors.
+
+void
+omni_thread::common_constructor(void* arg, priority_t pri, int det)
+{
+ _state = STATE_NEW;
+ _priority = pri;
+
+ next_id_mutex->lock();
+ _id = next_id++;
+ next_id_mutex->unlock();
+
+ thread_arg = arg;
+ detached = det; // may be altered in start_undetached()
+
+ _dummy = 0;
+ _values = 0;
+ _value_alloc = 0;
+ // sol_thread is set up in initialisation routine or start().
+}
+
+
+//
+// Destructor for omni_thread.
+//
+
+omni_thread::~omni_thread(void)
+{
+ DB(cerr << "destructor called for thread " << id() << endl);
+ if (_values) {
+ for (key_t i=0; i < _value_alloc; i++) {
+ if (_values[i]) {
+ delete _values[i];
+ }
+ }
+ delete [] _values;
+ }
+}
+
+
+//
+// Start the thread
+//
+
+void
+omni_thread::start(void)
+{
+ long flags = 0;
+
+ if (detached)
+ flags |= THR_DETACHED;
+
+ omni_mutex_lock l(mutex);
+
+ if (_state != STATE_NEW)
+ throw omni_thread_invalid();
+
+ THROW_ERRORS(thr_create(0, stack_size, omni_thread_wrapper, (void*)this, flags,
+ &sol_thread));
+
+ _state = STATE_RUNNING;
+
+ THROW_ERRORS(thr_setprio(sol_thread, sol_priority(_priority)));
+}
+
+
+//
+// Start a thread which will run the member function run_undetached().
+//
+
+void
+omni_thread::start_undetached(void)
+{
+ if ((fn_void != NULL) || (fn_ret != NULL))
+ throw omni_thread_invalid();
+
+ detached = 0;
+ start();
+}
+
+
+//
+// join - simply check error conditions & call thr_join.
+//
+
+void
+omni_thread::join(void** status)
+{
+ mutex.lock();
+
+ if ((_state != STATE_RUNNING) && (_state != STATE_TERMINATED)) {
+ mutex.unlock();
+ throw omni_thread_invalid();
+ }
+
+ mutex.unlock();
+
+ if (this == self())
+ throw omni_thread_invalid();
+
+ if (detached)
+ throw omni_thread_invalid();
+
+ DB(cerr << "omni_thread::join: doing thr_join\n");
+
+ THROW_ERRORS(thr_join(sol_thread, (thread_t *)NULL, status));
+
+ DB(cerr << "omni_thread::join: thr_join succeeded\n");
+
+ delete this;
+}
+
+
+//
+// Change this thread's priority.
+//
+
+void
+omni_thread::set_priority(priority_t pri)
+{
+ omni_mutex_lock l(mutex);
+
+ if (_state != STATE_RUNNING)
+ throw omni_thread_invalid();
+
+ _priority = pri;
+
+ THROW_ERRORS(thr_setprio(sol_thread, sol_priority(pri)));
+}
+
+
+//
+// create - construct a new thread object and start it running. Returns thread
+// object if successful, null pointer if not.
+//
+
+// detached version
+
+omni_thread*
+omni_thread::create(void (*fn)(void*), void* arg, priority_t pri)
+{
+ omni_thread* t = new omni_thread(fn, arg, pri);
+
+ t->start();
+
+ return t;
+}
+
+// undetached version
+
+omni_thread*
+omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri)
+{
+ omni_thread* t = new omni_thread(fn, arg, pri);
+
+ t->start();
+
+ return t;
+}
+
+
+//
+// exit() _must_ lock the mutex even in the case of a detached thread. This is
+// because a thread may run to completion before the thread that created it has
+// had a chance to get out of start(). By locking the mutex we ensure that the
+// creating thread must have reached the end of start() before we delete the
+// thread object. Of course, once the call to start() returns, the user can
+// still incorrectly refer to the thread object, but that's their problem.
+//
+
+void
+omni_thread::exit(void* return_value)
+{
+ omni_thread* me = self();
+
+ if (me)
+ {
+ me->mutex.lock();
+
+ me->_state = STATE_TERMINATED;
+
+ me->mutex.unlock();
+
+ DB(cerr << "omni_thread::exit: thread " << me->id() << " detached "
+ << me->detached << " return value " << return_value << endl);
+
+ if (me->detached)
+ delete me;
+ }
+ else
+ {
+ DB(cerr << "omni_thread::exit: called with a non-omnithread. Exit quietly." << endl);
+ }
+
+ thr_exit(return_value);
+}
+
+
+omni_thread*
+omni_thread::self(void)
+{
+ omni_thread* me;
+
+ THROW_ERRORS(thr_getspecific(self_key, (void**)&me));
+
+ if (!me) {
+ // This thread is not created by omni_thread::start because it
+ // doesn't has a class omni_thread instance attached to its key.
+ DB(cerr << "omni_thread::self: called with a non-ominthread. NULL is returned." << endl);
+ }
+
+ return me;
+}
+
+
+void
+omni_thread::yield(void)
+{
+ thr_yield();
+}
+
+
+void
+omni_thread::sleep(unsigned long secs, unsigned long nanosecs)
+{
+ timespec rqts = { secs, nanosecs };
+ timespec remain;
+ while (nanosleep(&rqts, &remain)) {
+ if (errno == EINTR) {
+ rqts.tv_sec = remain.tv_sec;
+ rqts.tv_nsec = remain.tv_nsec;
+ continue;
+ }
+ else
+ throw omni_thread_fatal(errno);
+ }
+}
+
+
+void
+omni_thread::get_time(unsigned long* abs_sec, unsigned long* abs_nsec,
+ unsigned long rel_sec, unsigned long rel_nsec)
+{
+ timespec abs;
+ clock_gettime(CLOCK_REALTIME, &abs);
+ abs.tv_nsec += rel_nsec;
+ abs.tv_sec += rel_sec + abs.tv_nsec / 1000000000;
+ abs.tv_nsec = abs.tv_nsec % 1000000000;
+ *abs_sec = abs.tv_sec;
+ *abs_nsec = abs.tv_nsec;
+}
+
+
+int
+omni_thread::sol_priority(priority_t pri)
+{
+ switch (pri) {
+
+ case PRIORITY_LOW:
+ return 0;
+
+ case PRIORITY_NORMAL:
+ return 1;
+
+ case PRIORITY_HIGH:
+ return 2;
+ }
+
+ throw omni_thread_invalid();
+}
+
+
+void
+omni_thread::stacksize(unsigned long sz)
+{
+ stack_size = sz;
+}
+
+unsigned long
+omni_thread::stacksize()
+{
+ return stack_size;
+}
+
+
+//
+// Dummy thread
+//
+
+#error This dummy thread code is not tested. It might work if you're lucky.
+
+class omni_thread_dummy : public omni_thread {
+public:
+ inline omni_thread_dummy() : omni_thread()
+ {
+ _dummy = 1;
+ _state = STATE_RUNNING;
+ sol_thread = thr_self();
+ THROW_ERRORS(thr_setspecific(self_key, (void*)this));
+ }
+ inline ~omni_thread_dummy()
+ {
+ THROW_ERRORS(thr_setspecific(self_key, 0));
+ }
+};
+
+omni_thread*
+omni_thread::create_dummy()
+{
+ if (omni_thread::self())
+ throw omni_thread_invalid();
+
+ return new omni_thread_dummy;
+}
+
+void
+omni_thread::release_dummy()
+{
+ omni_thread* self = omni_thread::self();
+ if (!self || !self->_dummy)
+ throw omni_thread_invalid();
+
+ omni_thread_dummy* dummy = (omni_thread_dummy*)self;
+ delete dummy;
+}
+
+
+#define INSIDE_THREAD_IMPL_CC
+#include "threaddata.cc"
+#undef INSIDE_THREAD_IMPL_CC
diff --git a/gnuradio-core/src/lib/omnithread/threaddata.cc b/gnuradio-core/src/lib/omnithread/threaddata.cc
new file mode 100644
index 0000000000..3d007714f6
--- /dev/null
+++ b/gnuradio-core/src/lib/omnithread/threaddata.cc
@@ -0,0 +1,83 @@
+// Package : omnithread
+// omnithread/threaddata.cc Created : 10/2000 dpg1
+//
+// Copyright (C) 2000 AT&T Laboratories Cambridge
+//
+// This file is part of the omnithread library
+//
+// The omnithread library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA
+//
+
+// Implementation of per-thread data
+
+#ifndef INSIDE_THREAD_IMPL_CC
+#error "threaddata.cc must be #included by a thread implementation."
+#endif
+
+
+static omni_thread::key_t allocated_keys = 0;
+
+omni_thread::key_t
+omni_thread::allocate_key()
+{
+ omni_mutex_lock l(*next_id_mutex);
+ return ++allocated_keys;
+}
+
+omni_thread::value_t*
+omni_thread::set_value(key_t k, value_t* v)
+{
+ if (k == 0) return 0;
+ if (k > _value_alloc) {
+ next_id_mutex->lock();
+ key_t alloc = allocated_keys;
+ next_id_mutex->unlock();
+
+ if (k > alloc) return 0;
+
+ value_t** nv = new value_t*[alloc];
+ key_t i = 0;
+ if (_values) {
+ for (; i < _value_alloc; i++)
+ nv[i] = _values[i];
+ delete [] _values;
+ }
+ for (; i < alloc; i++)
+ nv[i] = 0;
+
+ _values = nv;
+ _value_alloc = alloc;
+ }
+ if (_values[k-1]) delete _values[k-1];
+ _values[k-1] = v;
+ return v;
+}
+
+omni_thread::value_t*
+omni_thread::get_value(key_t k)
+{
+ if (k > _value_alloc) return 0;
+ return _values[k-1];
+}
+
+omni_thread::value_t*
+omni_thread::remove_value(key_t k)
+{
+ if (k > _value_alloc) return 0;
+ value_t* v = _values[k-1];
+ _values[k-1] = 0;
+ return v;
+}
diff --git a/gnuradio-core/src/lib/omnithread/vxWorks.cc b/gnuradio-core/src/lib/omnithread/vxWorks.cc
new file mode 100644
index 0000000000..25634ce938
--- /dev/null
+++ b/gnuradio-core/src/lib/omnithread/vxWorks.cc
@@ -0,0 +1,1160 @@
+//////////////////////////////////////////////////////////////////////////////
+// Filename: vxWorks.cc
+// Author: Tihomir Sokcevic
+// Acterna, Eningen.
+// Description: vxWorks adaptation of the omnithread wrapper classes
+// Notes: Munching strategy is imperative
+//////////////////////////////////////////////////////////////////////////////
+// $Log$
+// Revision 1.1 2004/04/10 18:00:52 eb
+// Initial revision
+//
+// Revision 1.1.1.1 2004/03/01 00:20:27 eb
+// initial checkin
+//
+// Revision 1.1 2003/05/25 05:29:04 eb
+// see ChangeLog
+//
+// Revision 1.1.2.1 2003/02/17 02:03:11 dgrisby
+// vxWorks port. (Thanks Michael Sturm / Acterna Eningen GmbH).
+//
+// Revision 1.1.1.1 2002/11/19 14:58:04 sokcevti
+// OmniOrb4.0.0 VxWorks port
+//
+// Revision 1.4 2002/10/15 07:54:09 kuttlest
+// change semaphore from SEM_FIFO to SEM_PRIO
+// ---
+//
+// Revision 1.3 2002/07/05 07:38:52 engeln
+// made priority redefinable on load time by defining int variables
+// omni_thread_prio_low = 220;
+// omni_thread_prio_normal = 110;
+// omni_thread_prio_high = 55;
+// the default priority is prio_normal.
+// The normal priority default has been increased from 200 to 110 and the
+// high priority from 100 to 55.
+// ---
+//
+// Revision 1.2 2002/06/14 12:44:57 engeln
+// replaced possibly unsafe wakeup procedure in broadcast.
+// ---
+//
+// Revision 1.1.1.1 2002/04/02 10:09:34 sokcevti
+// omniORB4 initial realease
+//
+// Revision 1.0 2001/10/23 14:22:45 sokcevti
+// Initial Version 4.00
+// ---
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Include files
+//////////////////////////////////////////////////////////////////////////////
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <time.h>
+#include <omnithread.h>
+#include <sysLib.h>
+
+#include <assert.h> // assert
+#include <intLib.h> // intContext
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Local defines
+//////////////////////////////////////////////////////////////////////////////
+#define ERRNO(x) (((x) != 0) ? (errno) : 0)
+#define THROW_ERRORS(x) { if((x) != OK) throw omni_thread_fatal(errno); }
+#define OMNI_THREAD_ID 0x7F7155AAl
+#define OMNI_STACK_SIZE 32768l
+
+#ifdef _DEBUG
+ #include <fstream>
+ #define DBG_TRACE(X) X
+#else // _DEBUG
+ #define DBG_TRACE(X)
+#endif // _DEBUG
+
+#define DBG_ASSERT(X)
+
+#define DBG_THROW(X) X
+
+int omni_thread_prio_low = 220;
+int omni_thread_prio_normal = 110;
+int omni_thread_prio_high = 55;
+///////////////////////////////////////////////////////////////////////////
+//
+// Mutex
+//
+///////////////////////////////////////////////////////////////////////////
+omni_mutex::omni_mutex(void):m_bConstructed(false)
+{
+ mutexID = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE);
+
+ DBG_ASSERT(assert(mutexID != NULL));
+
+ if(mutexID==NULL)
+ {
+ DBG_TRACE(cout<<"Exception: omni_mutex::omni_mutex() tid: "<<(int)taskIdSelf()<<endl);
+ DBG_THROW(throw omni_thread_fatal(-1));
+ }
+
+ m_bConstructed = true;
+}
+
+omni_mutex::~omni_mutex(void)
+{
+ m_bConstructed = false;
+
+ STATUS status = semDelete(mutexID);
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ DBG_TRACE(cout<<"Exception: omni_mutex::~omni_mutex() mutexID: "<<(int)mutexID<<" tid: "<<(int)taskIdSelf()<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+}
+
+/*
+void omni_mutex::lock(void)
+{
+ DBG_ASSERT(assert(!intContext())); // not in ISR context
+ DBG_ASSERT(assert(m_bConstructed));
+
+ STATUS status = semTake(mutexID, WAIT_FOREVER);
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ DBG_TRACE(cout<<"Exception: omni_mutex::lock() mutexID: "<<(int)mutexID<<" tid: "<<(int)taskIdSelf()<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+}
+
+void omni_mutex::unlock(void)
+{
+ DBG_ASSERT(assert(m_bConstructed));
+
+ STATUS status = semGive(mutexID);
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ DBG_TRACE(cout<<"Exception: omni_mutex::unlock() mutexID: "<<(int)mutexID<<" tid: "<<(int)taskIdSelf()<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+}
+*/
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Condition variable
+//
+///////////////////////////////////////////////////////////////////////////
+omni_condition::omni_condition(omni_mutex* m) : mutex(m)
+{
+ DBG_TRACE(cout<<"omni_condition::omni_condition mutexID: "<<(int)mutex->mutexID<<" tid:"<<(int)taskIdSelf()<<endl);
+
+ waiters_ = 0;
+
+ sema_ = semCCreate(SEM_Q_PRIORITY, 0);
+ if(sema_ == NULL)
+ {
+ DBG_TRACE(cout<<"Exception: omni_condition::omni_condition() tid: "<<(int)taskIdSelf()<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+
+ waiters_lock_ = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE);
+ if(waiters_lock_ == NULL)
+ {
+ DBG_TRACE(cout<<"Exception: omni_condition::omni_condition() tid: "<<(int)taskIdSelf()<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+
+}
+
+omni_condition::~omni_condition(void)
+{
+ STATUS status = semDelete(waiters_lock_);
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ DBG_TRACE(cout<<"Exception: omni_condition::~omni_condition"<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+
+ status = semDelete(sema_);
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ DBG_TRACE(cout<<"Exception: omni_condition::~omni_condition"<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+}
+
+void omni_condition::wait(void)
+{
+ DBG_TRACE(cout<<"omni_condition::wait mutexID: "<<(int)mutex->mutexID<<" tid:"<<(int)taskIdSelf()<<endl);
+
+ // Prevent race conditions on the <waiters_> count.
+
+ STATUS status = semTake(waiters_lock_,WAIT_FOREVER);
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ DBG_TRACE(cout<<"Exception: omni_condition::wait"<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+
+ ++waiters_;
+
+ status = semGive(waiters_lock_);
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ DBG_TRACE(cout<<"Exception: omni_condition::wait"<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+
+ // disable task lock to have an atomic unlock+semTake
+ taskLock();
+
+ // We keep the lock held just long enough to increment the count of
+ // waiters by one. Note that we can't keep it held across the call
+ // to wait() since that will deadlock other calls to signal().
+ mutex->unlock();
+
+ // Wait to be awakened by a cond_signal() or cond_broadcast().
+ status = semTake(sema_,WAIT_FOREVER);
+
+ // reenable task rescheduling
+ taskUnlock();
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ DBG_TRACE(cout<<"Exception: omni_condition::wait"<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+
+ // Reacquire lock to avoid race conditions on the <waiters_> count.
+ status = semTake(waiters_lock_,WAIT_FOREVER);
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ DBG_TRACE(cout<<"Exception: omni_condition::wait"<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+
+ // We're ready to return, so there's one less waiter.
+ --waiters_;
+
+ // Release the lock so that other collaborating threads can make
+ // progress.
+ status = semGive(waiters_lock_);
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ DBG_TRACE(cout<<"Exception: omni_condition::wait"<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+
+ // Bad things happened, so let's just return below.
+
+ // We must always regain the <external_mutex>, even when errors
+ // occur because that's the guarantee that we give to our callers.
+ mutex->lock();
+}
+
+
+// The time given is absolute. Return 0 is timeout
+int omni_condition::timedwait(unsigned long secs, unsigned long nanosecs)
+{
+ STATUS result = OK;
+ timespec now;
+ unsigned long timeout;
+ int ticks;
+
+ // Prevent race conditions on the <waiters_> count.
+ STATUS status = semTake(waiters_lock_, WAIT_FOREVER);
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ DBG_TRACE(cout<<"Exception: omni_condition::timedwait"<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+
+ ++waiters_;
+
+ status = semGive(waiters_lock_);
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ DBG_TRACE(cout<<"Exception: omni_condition::timedwait"<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+
+ clock_gettime(CLOCK_REALTIME, &now);
+
+ if(((unsigned long)secs <= (unsigned long)now.tv_sec) &&
+ (((unsigned long)secs < (unsigned long)now.tv_sec) ||
+ (nanosecs < (unsigned long)now.tv_nsec)))
+ timeout = 0;
+ else
+ timeout = (secs-now.tv_sec) * 1000 + (nanosecs-now.tv_nsec) / 1000000l;
+
+ // disable task lock to have an atomic unlock+semTake
+ taskLock();
+
+ // We keep the lock held just long enough to increment the count
+ // of waiters by one.
+ mutex->unlock();
+
+ // Wait to be awakened by a signal() or broadcast().
+ ticks = (timeout * sysClkRateGet()) / 1000L;
+ result = semTake(sema_, ticks);
+
+ // reenable task rescheduling
+ taskUnlock();
+
+ // Reacquire lock to avoid race conditions.
+ status = semTake(waiters_lock_, WAIT_FOREVER);
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ DBG_TRACE(cout<<"Exception: omni_condition::timedwait"<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+
+ --waiters_;
+
+ status = semGive(waiters_lock_);
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ DBG_TRACE(cout<<"Exception: omni_condition::timedwait"<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+
+ // A timeout has occured - fires exception if the origin is other than timeout
+ if(result!=OK && !(errno == S_objLib_OBJ_TIMEOUT || errno == S_objLib_OBJ_UNAVAILABLE))
+ {
+ DBG_TRACE(cout<<"omni_condition::timedwait! - thread:"<<omni_thread::self()->id()<<" SemID:"<<(int)sema_<<" errno:"<<errno<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+
+ // We must always regain the <external_mutex>, even when errors
+ // occur because that's the guarantee that we give to our callers.
+ mutex->lock();
+
+ if(result!=OK) // timeout
+ return 0;
+
+ return 1;
+}
+
+void omni_condition::signal(void)
+{
+ DBG_TRACE(cout<<"omni_condition::signal mutexID: "<<(int)mutex->mutexID<<" tid:"<<(int)taskIdSelf()<<endl);
+
+ STATUS status = semTake(waiters_lock_, WAIT_FOREVER);
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ DBG_TRACE(cout<<"Exception: omni_condition::signal"<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+
+ int have_waiters = waiters_ > 0;
+
+ status = semGive(waiters_lock_);
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ DBG_TRACE(cout<<"Exception: omni_condition::signal"<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+
+ if(have_waiters != 0)
+ {
+ status = semGive(sema_);
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ DBG_TRACE(cout<<"Exception: omni_condition::signal"<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+ }
+}
+
+void omni_condition::broadcast(void)
+{
+ DBG_TRACE(cout<<"omni_condition::broadcast mutexID: "<<(int)mutex->mutexID<<" tid:"<<(int)taskIdSelf()<<endl);
+
+ int have_waiters = 0;
+
+ // The <external_mutex> must be locked before this call is made.
+ // This is needed to ensure that <waiters_> and <was_broadcast_> are
+ // consistent relative to each other.
+ STATUS status = semTake(waiters_lock_, WAIT_FOREVER);
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ DBG_TRACE(cout<<"Exception: omni_condition::signal"<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+
+ if(waiters_ > 0)
+ {
+ // We are broadcasting, even if there is just one waiter...
+ // Record the fact that we are broadcasting. This helps the
+ // cond_wait() method know how to optimize itself. Be sure to
+ // set this with the <waiters_lock_> held.
+ have_waiters = 1;
+ }
+
+ status = semGive(waiters_lock_);
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ DBG_TRACE(cout<<"Exception: omni_condition::signal"<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+
+ if(have_waiters)
+ {
+ // Wake up all the waiters.
+ status = semFlush(sema_);
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ DBG_TRACE(cout<<"omni_condition::broadcast1! - thread:"<<omni_thread::self()->id()<<" SemID:"<<(int)sema_<<" errno:"<<errno<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Counting semaphore
+//
+///////////////////////////////////////////////////////////////////////////
+omni_semaphore::omni_semaphore(unsigned int initial)
+{
+
+ DBG_ASSERT(assert(0 <= (int)initial)); // POSIX expects only unsigned init values
+
+ semID = semCCreate(SEM_Q_PRIORITY, (int)initial);
+
+ DBG_ASSERT(assert(semID!=NULL));
+
+ if(semID==NULL)
+ {
+ DBG_TRACE(cout<<"Exception: omni_semaphore::omni_semaphore"<<endl);
+ DBG_THROW(throw omni_thread_fatal(-1));
+ }
+}
+
+omni_semaphore::~omni_semaphore(void)
+{
+ STATUS status = semDelete(semID);
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ DBG_TRACE(cout<<"Exception: omni_semaphore::~omni_semaphore"<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+}
+
+void omni_semaphore::wait(void)
+{
+ DBG_ASSERT(assert(!intContext())); // no wait in ISR
+
+ STATUS status = semTake(semID, WAIT_FOREVER);
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ DBG_TRACE(cout<<"Exception: omni_semaphore::wait"<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+}
+
+int omni_semaphore::trywait(void)
+{
+ STATUS status = semTake(semID, NO_WAIT);
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ if(errno == S_objLib_OBJ_UNAVAILABLE)
+ {
+ return 0;
+ }
+ else
+ {
+ DBG_ASSERT(assert(false));
+
+ DBG_TRACE(cout<<"Exception: omni_semaphore::trywait"<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+ }
+
+ return 1;
+}
+
+void omni_semaphore::post(void)
+{
+ STATUS status = semGive(semID);
+
+ DBG_ASSERT(assert(status == OK));
+
+ if(status != OK)
+ {
+ DBG_TRACE(cout<<"Exception: omni_semaphore::post"<<endl);
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Thread
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//
+// static variables
+//
+omni_mutex* omni_thread::next_id_mutex = 0;
+int omni_thread::next_id = 0;
+
+// omniORB requires a larger stack size than the default (21120) on OSF/1
+static size_t stack_size = OMNI_STACK_SIZE;
+
+
+//
+// Initialisation function (gets called before any user code).
+//
+
+static int& count() {
+ static int the_count = 0;
+ return the_count;
+}
+
+omni_thread::init_t::init_t(void)
+{
+ // Only do it once however many objects get created.
+ if(count()++ != 0)
+ return;
+
+ attach();
+}
+
+omni_thread::init_t::~init_t(void)
+{
+ if (--count() != 0) return;
+
+ omni_thread* self = omni_thread::self();
+ if (!self) return;
+
+ taskTcb(taskIdSelf())->spare1 = 0;
+ delete self;
+
+ delete next_id_mutex;
+}
+
+
+//
+// Wrapper for thread creation.
+//
+extern "C" void omni_thread_wrapper(void* ptr)
+{
+ omni_thread* me = (omni_thread*)ptr;
+
+ DBG_TRACE(cout<<"omni_thread_wrapper: thread "<<me->id()<<" started\n");
+
+ //
+ // We can now tweaked the task info since the tcb exist now
+ //
+ me->mutex.lock(); // To ensure that start has had time to finish
+ taskTcb(me->tid)->spare1 = OMNI_THREAD_ID;
+ taskTcb(me->tid)->spare2 = (int)ptr;
+ me->mutex.unlock();
+
+ //
+ // Now invoke the thread function with the given argument.
+ //
+ if(me->fn_void != NULL)
+ {
+ (*me->fn_void)(me->thread_arg);
+ omni_thread::exit();
+ }
+
+ if(me->fn_ret != NULL)
+ {
+ void* return_value = (*me->fn_ret)(me->thread_arg);
+ omni_thread::exit(return_value);
+ }
+
+ if(me->detached)
+ {
+ me->run(me->thread_arg);
+ omni_thread::exit();
+ }
+ else
+ {
+ void* return_value = me->run_undetached(me->thread_arg);
+ omni_thread::exit(return_value);
+ }
+}
+
+
+//
+// Special functions for VxWorks only
+//
+void omni_thread::attach(void)
+{
+ DBG_TRACE(cout<<"omni_thread_attach: VxWorks mapping thread initialising\n");
+
+ int _tid = taskIdSelf();
+
+ // Check the task is not already attached
+ if(taskTcb(_tid)->spare1 == OMNI_THREAD_ID)
+ return;
+
+ // Create the mutex required to lock the threads debugging id (create before the thread!!!)
+ if(next_id_mutex == 0)
+ next_id_mutex = new omni_mutex;
+
+ // Create a thread object for THIS running process
+ omni_thread* t = new omni_thread;
+
+ // Lock its mutex straigh away!
+ omni_mutex_lock l(t->mutex);
+
+ // Adjust data members of this instance
+ t->_state = STATE_RUNNING;
+ t->tid = taskIdSelf();
+
+ // Set the thread values so it can be recongnised as a omni_thread
+ // Set the id last can possibly prevent race condition
+ taskTcb(t->tid)->spare2 = (int)t;
+ taskTcb(t->tid)->spare1 = OMNI_THREAD_ID;
+
+ // Create the running_mutex at this stage, but leave it empty. We are not running
+ // in the task context HERE, so taking it would be disastrous.
+ t->running_cond = new omni_condition(&t->mutex);
+}
+
+
+void omni_thread::detach(void)
+{
+ DBG_TRACE(cout<<"omni_thread_detach: VxWorks detaching thread mapping\n");
+
+ int _tid = taskIdSelf();
+
+ // Check the task has a OMNI_THREAD attached
+ if(taskTcb(_tid)->spare1 != OMNI_THREAD_ID)
+ return;
+
+ // Invalidate the id NOW !
+ taskTcb(_tid)->spare1 = 0;
+
+ // Even if NULL, it is safe to delete the thread
+ omni_thread* t = (omni_thread*)taskTcb(_tid)->spare2;
+ // Fininsh cleaning the tcb structure
+ taskTcb(_tid)->spare2 = 0;
+
+ delete t;
+}
+
+
+//
+// Constructors for omni_thread - set up the thread object but don't
+// start it running.
+//
+
+// construct a detached thread running a given function.
+omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri)
+{
+ common_constructor(arg, pri, 1);
+ fn_void = fn;
+ fn_ret = NULL;
+}
+
+// construct an undetached thread running a given function.
+omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri)
+{
+ common_constructor(arg, pri, 0);
+ fn_void = NULL;
+ fn_ret = fn;
+}
+
+// construct a thread which will run either run() or run_undetached().
+
+omni_thread::omni_thread(void* arg, priority_t pri)
+{
+ common_constructor(arg, pri, 1);
+ fn_void = NULL;
+ fn_ret = NULL;
+}
+
+// common part of all constructors.
+void omni_thread::common_constructor(void* arg, priority_t pri, int det)
+{
+ _state = STATE_NEW;
+ _priority = pri;
+
+ // Set the debugging id
+ next_id_mutex->lock();
+ _id = next_id++;
+ next_id_mutex->unlock();
+
+ // Note : tid can only be setup when the task is up and running
+ tid = 0;
+
+ thread_arg = arg;
+ detached = det; // may be altered in start_undetached()
+
+ _dummy = 0;
+ _values = 0;
+ _value_alloc = 0;
+}
+
+//
+// Destructor for omni_thread.
+//
+omni_thread::~omni_thread(void)
+{
+ DBG_TRACE(cout<<"omni_thread::~omni_thread for thread "<<id()<<endl);
+
+ if (_values) {
+ for (key_t i=0; i < _value_alloc; i++) {
+ if (_values[i]) {
+ delete _values[i];
+ }
+ }
+ delete [] _values;
+ }
+
+ delete running_cond;
+}
+
+
+//
+// Start the thread
+//
+void omni_thread::start(void)
+{
+ omni_mutex_lock l(mutex);
+
+ DBG_ASSERT(assert(_state == STATE_NEW));
+
+ if(_state != STATE_NEW)
+ DBG_THROW(throw omni_thread_invalid());
+
+ // Allocate memory for the task. (The returned id cannot be trusted by the task)
+ tid = taskSpawn(
+ NULL, // Task name
+ vxworks_priority(_priority), // Priority
+ 0, // Option
+ stack_size, // Stack size
+ (FUNCPTR)omni_thread_wrapper, // Priority
+ (int)this, // First argument is this
+ 0,0,0,0,0,0,0,0,0 // Remaining unused args
+ );
+
+ DBG_ASSERT(assert(tid!=ERROR));
+
+ if(tid==ERROR)
+ DBG_THROW(throw omni_thread_invalid());
+
+ _state = STATE_RUNNING;
+
+ // Create the running_mutex at this stage, but leave it empty. We are not running
+ // in the task context HERE, so taking it would be disastrous.
+ running_cond = new omni_condition(&mutex);
+}
+
+
+//
+// Start a thread which will run the member function run_undetached().
+//
+void omni_thread::start_undetached(void)
+{
+ DBG_ASSERT(assert(!((fn_void != NULL) || (fn_ret != NULL))));
+
+ if((fn_void != NULL) || (fn_ret != NULL))
+ DBG_THROW(throw omni_thread_invalid());
+
+ detached = 0;
+
+ start();
+}
+
+
+//
+// join - Wait for the task to complete before returning to the calling process
+//
+void omni_thread::join(void** status)
+{
+ mutex.lock();
+
+ if((_state != STATE_RUNNING) && (_state != STATE_TERMINATED))
+ {
+ mutex.unlock();
+
+ DBG_ASSERT(assert(false));
+
+ DBG_THROW(throw omni_thread_invalid());
+ }
+
+ mutex.unlock();
+
+ DBG_ASSERT(assert(this != self()));
+
+ if(this == self())
+ DBG_THROW(throw omni_thread_invalid());
+
+ DBG_ASSERT(assert(!detached));
+
+ if(detached)
+ DBG_THROW(throw omni_thread_invalid());
+
+ mutex.lock();
+ running_cond->wait();
+ mutex.unlock();
+
+ if(status)
+ *status = return_val;
+
+ delete this;
+}
+
+
+//
+// Change this thread's priority.
+//
+void omni_thread::set_priority(priority_t pri)
+{
+ omni_mutex_lock l(mutex);
+
+ DBG_ASSERT(assert(_state == STATE_RUNNING));
+
+ if(_state != STATE_RUNNING)
+ {
+ DBG_THROW(throw omni_thread_invalid());
+ }
+
+ _priority = pri;
+
+ if(taskPrioritySet(tid, vxworks_priority(pri))==ERROR)
+ {
+ DBG_ASSERT(assert(false));
+
+ DBG_THROW(throw omni_thread_fatal(errno));
+ }
+}
+
+
+//
+// create - construct a new thread object and start it running. Returns thread
+// object if successful, null pointer if not.
+//
+
+// detached version (the entry point is a void)
+omni_thread* omni_thread::create(void (*fn)(void*), void* arg, priority_t pri)
+{
+ omni_thread* t = new omni_thread(fn, arg, pri);
+
+ t->start();
+
+ return t;
+}
+
+// undetached version (the entry point is a void*)
+omni_thread* omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri)
+{
+ omni_thread* t = new omni_thread(fn, arg, pri);
+
+ t->start();
+
+ return t;
+}
+
+
+//
+// exit() _must_ lock the mutex even in the case of a detached thread. This is
+// because a thread may run to completion before the thread that created it has
+// had a chance to get out of start(). By locking the mutex we ensure that the
+// creating thread must have reached the end of start() before we delete the
+// thread object. Of course, once the call to start() returns, the user can
+// still incorrectly refer to the thread object, but that's their problem.
+//
+void omni_thread::exit(void* return_value)
+{
+ omni_thread* me = self();
+
+ if(me)
+ {
+ me->mutex.lock();
+
+ me->return_val = return_value;
+ me->_state = STATE_TERMINATED;
+ me->running_cond->signal();
+
+ me->mutex.unlock();
+
+ DBG_TRACE(cout<<"omni_thread::exit: thread "<<me->id()<<" detached "<<me->detached<<" return value "<<(int)return_value<<endl);
+
+ if(me->detached)
+ delete me;
+ }
+ else
+ DBG_TRACE(cout<<"omni_thread::exit: called with a non-omnithread. Exit quietly."<<endl);
+
+ taskDelete(taskIdSelf());
+}
+
+
+omni_thread* omni_thread::self(void)
+{
+ if(taskTcb(taskIdSelf())->spare1 != OMNI_THREAD_ID)
+ return NULL;
+
+ return (omni_thread*)taskTcb(taskIdSelf())->spare2;
+}
+
+
+void omni_thread::yield(void)
+{
+ taskDelay(NO_WAIT);
+}
+
+
+void omni_thread::sleep(unsigned long secs, unsigned long nanosecs)
+{
+ int tps = sysClkRateGet();
+
+ // Convert to us to avoid overflow in the multiplication
+ // tps should always be less than 1000 !
+ nanosecs /= 1000;
+
+ taskDelay(secs*tps + (nanosecs*tps)/1000000l);
+}
+
+
+void omni_thread::get_time( unsigned long* abs_sec,
+ unsigned long* abs_nsec,
+ unsigned long rel_sec,
+ unsigned long rel_nsec)
+{
+ timespec abs;
+ clock_gettime(CLOCK_REALTIME, &abs);
+ abs.tv_nsec += rel_nsec;
+ abs.tv_sec += rel_sec + abs.tv_nsec / 1000000000;
+ abs.tv_nsec = abs.tv_nsec % 1000000000;
+ *abs_sec = abs.tv_sec;
+ *abs_nsec = abs.tv_nsec;
+}
+
+
+int omni_thread::vxworks_priority(priority_t pri)
+{
+ switch (pri)
+ {
+ case PRIORITY_LOW:
+ return omni_thread_prio_low;
+
+ case PRIORITY_NORMAL:
+ return omni_thread_prio_normal;
+
+ case PRIORITY_HIGH:
+ return omni_thread_prio_high;
+ }
+
+ DBG_ASSERT(assert(false));
+
+ DBG_THROW(throw omni_thread_invalid());
+}
+
+
+void omni_thread::stacksize(unsigned long sz)
+{
+ stack_size = sz;
+}
+
+
+unsigned long omni_thread::stacksize()
+{
+ return stack_size;
+}
+
+
+void omni_thread::show(void)
+{
+ omni_thread *pThread;
+ int s1, s2;
+ int tid = taskIdSelf();
+
+ printf("TaskId is %.8x\n", tid);
+
+ s1 = taskTcb(tid)->spare1;
+
+ if(s1 != OMNI_THREAD_ID)
+ {
+ printf("Spare 1 is %.8x, and not recongnized\n", s1);
+
+ return;
+ }
+ else
+ {
+ printf("Spare 1 indicate an omni_thread.\n");
+ }
+
+ s2 = taskTcb(tid)->spare2;
+
+ if(s2 == 0)
+ {
+ printf("Spare 2 is NULL! - No thread object attached !!\n");
+
+ return;
+ }
+ else
+ {
+ printf("Thread object at %.8x\n", s2);
+ }
+
+ pThread = (omni_thread *)s2;
+
+ state_t status = pThread->_state;
+
+ printf(" | Thread status is ");
+
+ switch (status)
+ {
+ case STATE_NEW:
+ printf("NEW\n"); break;
+ case STATE_RUNNING:
+ printf("STATE_RUNNING\n"); break;
+ case STATE_TERMINATED:
+ printf("TERMINATED\n"); break;
+ default:
+ printf("Illegal (=%.8x)\n", (unsigned int)status);
+
+ return;
+ }
+
+ if(pThread->tid != tid)
+ {
+ printf(" | Task ID in thread object is different!! (=%.8x)\n", pThread->tid);
+
+ return;
+ }
+ else
+ {
+ printf(" | Task ID in thread consistent\n");
+ }
+
+ printf("\n");
+}
+
+
+//
+// Dummy thread
+//
+
+class omni_thread_dummy : public omni_thread {
+public:
+ inline omni_thread_dummy() : omni_thread()
+ {
+ _dummy = 1;
+ _state = STATE_RUNNING;
+
+ // Adjust data members of this instance
+ tid = taskIdSelf();
+
+ // Set the thread values so it can be recongnised as a omni_thread
+ // Set the id last can possibly prevent race condition
+ taskTcb(tid)->spare2 = (int)this;
+ taskTcb(tid)->spare1 = OMNI_THREAD_ID;
+ }
+ inline ~omni_thread_dummy()
+ {
+ taskTcb(taskIdSelf())->spare1 = 0;
+ }
+};
+
+omni_thread*
+omni_thread::create_dummy()
+{
+ if (omni_thread::self())
+ throw omni_thread_invalid();
+
+ return new omni_thread_dummy;
+}
+
+void
+omni_thread::release_dummy()
+{
+ omni_thread* self = omni_thread::self();
+ if (!self || !self->_dummy)
+ throw omni_thread_invalid();
+
+ omni_thread_dummy* dummy = (omni_thread_dummy*)self;
+ delete dummy;
+}
+
+
+#define INSIDE_THREAD_IMPL_CC
+#include "threaddata.cc"
+#undef INSIDE_THREAD_IMPL_CC
diff --git a/gnuradio-core/src/lib/reed-solomon/Makefile.am b/gnuradio-core/src/lib/reed-solomon/Makefile.am
new file mode 100644
index 0000000000..71af766415
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/Makefile.am
@@ -0,0 +1,55 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+include $(top_srcdir)/Makefile.common
+
+# Note, this Makefile.am only builds the char versions of the reed soloman routines.
+# If you need the int versions too, please figure out how to add them *cleanly* to
+# this Makefile.am.
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(CPPUNIT_INCLUDES)
+
+TESTS = rstest
+
+EXTRA_DIST = \
+ README.karn
+
+noinst_LTLIBRARIES = librs.la
+
+noinst_PROGRAMS = \
+ rstest
+
+librs_la_SOURCES = \
+ encode_rs.c \
+ decode_rs.c \
+ init_rs.c
+
+grinclude_HEADERS = \
+ rs.h
+
+noinst_HEADERS = \
+ ccsds.h \
+ char.h \
+ int.h \
+ fixed.h
+
+rstest_SOURCES = rstest.c exercise.c
+rstest_LDADD = librs.la
diff --git a/gnuradio-core/src/lib/reed-solomon/Makefile.in.karn b/gnuradio-core/src/lib/reed-solomon/Makefile.in.karn
new file mode 100644
index 0000000000..8550b41581
--- /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 0000000000..341832dbd5
--- /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 0000000000..f30644ffea
--- /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 0000000000..0f2bde6186
--- /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 0000000000..2fbcb504aa
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/char.h
@@ -0,0 +1,56 @@
+/* Include file to configure the RS codec for character symbols
+ *
+ * Copyright 2002, Phil Karn, KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+
+#define DTYPE unsigned char
+
+/* Reed-Solomon codec control block */
+struct rs {
+ unsigned int mm; /* Bits per symbol */
+ unsigned int nn; /* Symbols per block (= (1<<mm)-1) */
+ unsigned char *alpha_to; /* log lookup table */
+ unsigned char *index_of; /* Antilog lookup table */
+ unsigned char *genpoly; /* Generator polynomial */
+ unsigned int nroots; /* Number of generator roots = number of parity symbols */
+ unsigned char fcr; /* First consecutive root, index form */
+ unsigned char prim; /* Primitive element, index form */
+ unsigned char iprim; /* prim-th root of 1, index form */
+};
+
+static inline int modnn(struct rs *rs,int x){
+ while (x >= rs->nn) {
+ x -= rs->nn;
+ x = (x >> rs->mm) + (x & rs->nn);
+ }
+ return x;
+}
+#define MODNN(x) modnn(rs,x)
+
+#define MM (rs->mm)
+#define NN (rs->nn)
+#define ALPHA_TO (rs->alpha_to)
+#define INDEX_OF (rs->index_of)
+#define GENPOLY (rs->genpoly)
+#define NROOTS (rs->nroots)
+#define FCR (rs->fcr)
+#define PRIM (rs->prim)
+#define IPRIM (rs->iprim)
+#define A0 (NN)
+
+#define ENCODE_RS encode_rs_char
+#define DECODE_RS decode_rs_char
+#define INIT_RS init_rs_char
+#define FREE_RS free_rs_char
+
+void ENCODE_RS(void *p,DTYPE *data,DTYPE *parity);
+int DECODE_RS(void *p,DTYPE *data,int *eras_pos,int no_eras);
+void *INIT_RS(unsigned int symsize,unsigned int gfpoly,unsigned int fcr,
+ unsigned int prim,unsigned int nroots);
+void FREE_RS(void *p);
+
+
+
+
+
diff --git a/gnuradio-core/src/lib/reed-solomon/decode_rs.c b/gnuradio-core/src/lib/reed-solomon/decode_rs.c
new file mode 100644
index 0000000000..ca409782fa
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/decode_rs.c
@@ -0,0 +1,262 @@
+/* Reed-Solomon decoder
+ * Copyright 2002 Phil Karn, KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#include <string.h>
+
+#define NULL ((void *)0)
+#define min(a,b) ((a) < (b) ? (a) : (b))
+
+#ifdef FIXED
+#include "fixed.h"
+#elif defined(BIGSYM)
+#include "int.h"
+#else
+#include "char.h"
+#endif
+
+int DECODE_RS(
+#ifndef FIXED
+void *p,
+#endif
+DTYPE *data, int *eras_pos, int no_eras){
+
+#ifndef FIXED
+ struct rs *rs = (struct rs *)p;
+#endif
+ int deg_lambda, el, deg_omega;
+ int i, j, r,k;
+ DTYPE u,q,tmp,num1,num2,den,discr_r;
+ DTYPE lambda[NROOTS+1], s[NROOTS]; /* Err+Eras Locator poly
+ * and syndrome poly */
+ DTYPE b[NROOTS+1], t[NROOTS+1], omega[NROOTS+1];
+ DTYPE root[NROOTS], reg[NROOTS+1], loc[NROOTS];
+ int syn_error, count;
+
+ /* form the syndromes; i.e., evaluate data(x) at roots of g(x) */
+ for(i=0;i<NROOTS;i++)
+ s[i] = data[0];
+
+ for(j=1;j<NN;j++){
+ for(i=0;i<NROOTS;i++){
+ if(s[i] == 0){
+ s[i] = data[j];
+ } else {
+ s[i] = data[j] ^ ALPHA_TO[MODNN(INDEX_OF[s[i]] + (FCR+i)*PRIM)];
+ }
+ }
+ }
+
+ /* Convert syndromes to index form, checking for nonzero condition */
+ syn_error = 0;
+ for(i=0;i<NROOTS;i++){
+ syn_error |= s[i];
+ s[i] = INDEX_OF[s[i]];
+ }
+
+ if (!syn_error) {
+ /* if syndrome is zero, data[] is a codeword and there are no
+ * errors to correct. So return data[] unmodified
+ */
+ count = 0;
+ goto finish;
+ }
+ memset(&lambda[1],0,NROOTS*sizeof(lambda[0]));
+ lambda[0] = 1;
+
+ if (no_eras > 0) {
+ /* Init lambda to be the erasure locator polynomial */
+ lambda[1] = ALPHA_TO[MODNN(PRIM*(NN-1-eras_pos[0]))];
+ for (i = 1; i < no_eras; i++) {
+ u = MODNN(PRIM*(NN-1-eras_pos[i]));
+ for (j = i+1; j > 0; j--) {
+ tmp = INDEX_OF[lambda[j - 1]];
+ if(tmp != A0)
+ lambda[j] ^= ALPHA_TO[MODNN(u + tmp)];
+ }
+ }
+
+#if DEBUG >= 1
+ /* Test code that verifies the erasure locator polynomial just constructed
+ Needed only for decoder debugging. */
+
+ /* find roots of the erasure location polynomial */
+ for(i=1;i<=no_eras;i++)
+ reg[i] = INDEX_OF[lambda[i]];
+
+ count = 0;
+ for (i = 1,k=IPRIM-1; i <= NN; i++,k = MODNN(k+IPRIM)) {
+ q = 1;
+ for (j = 1; j <= no_eras; j++)
+ if (reg[j] != A0) {
+ reg[j] = MODNN(reg[j] + j);
+ q ^= ALPHA_TO[reg[j]];
+ }
+ if (q != 0)
+ continue;
+ /* store root and error location number indices */
+ root[count] = i;
+ loc[count] = k;
+ count++;
+ }
+ if (count != no_eras) {
+ printf("count = %d no_eras = %d\n lambda(x) is WRONG\n",count,no_eras);
+ count = -1;
+ goto finish;
+ }
+#if DEBUG >= 2
+ printf("\n Erasure positions as determined by roots of Eras Loc Poly:\n");
+ for (i = 0; i < count; i++)
+ printf("%d ", loc[i]);
+ printf("\n");
+#endif
+#endif
+ }
+ for(i=0;i<NROOTS+1;i++)
+ b[i] = INDEX_OF[lambda[i]];
+
+ /*
+ * Begin Berlekamp-Massey algorithm to determine error+erasure
+ * locator polynomial
+ */
+ r = no_eras;
+ el = no_eras;
+ while (++r <= NROOTS) { /* r is the step number */
+ /* Compute discrepancy at the r-th step in poly-form */
+ discr_r = 0;
+ for (i = 0; i < r; i++){
+ if ((lambda[i] != 0) && (s[r-i-1] != A0)) {
+ discr_r ^= ALPHA_TO[MODNN(INDEX_OF[lambda[i]] + s[r-i-1])];
+ }
+ }
+ discr_r = INDEX_OF[discr_r]; /* Index form */
+ if (discr_r == A0) {
+ /* 2 lines below: B(x) <-- x*B(x) */
+ memmove(&b[1],b,NROOTS*sizeof(b[0]));
+ b[0] = A0;
+ } else {
+ /* 7 lines below: T(x) <-- lambda(x) - discr_r*x*b(x) */
+ t[0] = lambda[0];
+ for (i = 0 ; i < NROOTS; i++) {
+ if(b[i] != A0)
+ t[i+1] = lambda[i+1] ^ ALPHA_TO[MODNN(discr_r + b[i])];
+ else
+ t[i+1] = lambda[i+1];
+ }
+ if (2 * el <= r + no_eras - 1) {
+ el = r + no_eras - el;
+ /*
+ * 2 lines below: B(x) <-- inv(discr_r) *
+ * lambda(x)
+ */
+ for (i = 0; i <= NROOTS; i++)
+ b[i] = (lambda[i] == 0) ? A0 : MODNN(INDEX_OF[lambda[i]] - discr_r + NN);
+ } else {
+ /* 2 lines below: B(x) <-- x*B(x) */
+ memmove(&b[1],b,NROOTS*sizeof(b[0]));
+ b[0] = A0;
+ }
+ memcpy(lambda,t,(NROOTS+1)*sizeof(t[0]));
+ }
+ }
+
+ /* Convert lambda to index form and compute deg(lambda(x)) */
+ deg_lambda = 0;
+ for(i=0;i<NROOTS+1;i++){
+ lambda[i] = INDEX_OF[lambda[i]];
+ if(lambda[i] != A0)
+ deg_lambda = i;
+ }
+ /* Find roots of the error+erasure locator polynomial by Chien search */
+ memcpy(&reg[1],&lambda[1],NROOTS*sizeof(reg[0]));
+ count = 0; /* Number of roots of lambda(x) */
+ for (i = 1,k=IPRIM-1; i <= NN; i++,k = MODNN(k+IPRIM)) {
+ q = 1; /* lambda[0] is always 0 */
+ for (j = deg_lambda; j > 0; j--){
+ if (reg[j] != A0) {
+ reg[j] = MODNN(reg[j] + j);
+ q ^= ALPHA_TO[reg[j]];
+ }
+ }
+ if (q != 0)
+ continue; /* Not a root */
+ /* store root (index-form) and error location number */
+#if DEBUG>=2
+ printf("count %d root %d loc %d\n",count,i,k);
+#endif
+ root[count] = i;
+ loc[count] = k;
+ /* If we've already found max possible roots,
+ * abort the search to save time
+ */
+ if(++count == deg_lambda)
+ break;
+ }
+ if (deg_lambda != count) {
+ /*
+ * deg(lambda) unequal to number of roots => uncorrectable
+ * error detected
+ */
+ count = -1;
+ goto finish;
+ }
+ /*
+ * Compute err+eras evaluator poly omega(x) = s(x)*lambda(x) (modulo
+ * x**NROOTS). in index form. Also find deg(omega).
+ */
+ deg_omega = 0;
+ for (i = 0; i < NROOTS;i++){
+ tmp = 0;
+ j = (deg_lambda < i) ? deg_lambda : i;
+ for(;j >= 0; j--){
+ if ((s[i - j] != A0) && (lambda[j] != A0))
+ tmp ^= ALPHA_TO[MODNN(s[i - j] + lambda[j])];
+ }
+ if(tmp != 0)
+ deg_omega = i;
+ omega[i] = INDEX_OF[tmp];
+ }
+ omega[NROOTS] = A0;
+
+ /*
+ * Compute error values in poly-form. num1 = omega(inv(X(l))), num2 =
+ * inv(X(l))**(FCR-1) and den = lambda_pr(inv(X(l))) all in poly-form
+ */
+ for (j = count-1; j >=0; j--) {
+ num1 = 0;
+ for (i = deg_omega; i >= 0; i--) {
+ if (omega[i] != A0)
+ num1 ^= ALPHA_TO[MODNN(omega[i] + i * root[j])];
+ }
+ num2 = ALPHA_TO[MODNN(root[j] * (FCR - 1) + NN)];
+ den = 0;
+
+ /* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */
+ for (i = min(deg_lambda,NROOTS-1) & ~1; i >= 0; i -=2) {
+ if(lambda[i+1] != A0)
+ den ^= ALPHA_TO[MODNN(lambda[i+1] + i * root[j])];
+ }
+ if (den == 0) {
+#if DEBUG >= 1
+ printf("\n ERROR: denominator = 0\n");
+#endif
+ count = -1;
+ goto finish;
+ }
+ /* Apply error to data */
+ if (num1 != 0) {
+ data[loc[j]] ^= ALPHA_TO[MODNN(INDEX_OF[num1] + INDEX_OF[num2] + NN - INDEX_OF[den])];
+ }
+ }
+ finish:
+ if(eras_pos != NULL){
+ for(i=0;i<count;i++)
+ eras_pos[i] = loc[i];
+ }
+ return count;
+}
diff --git a/gnuradio-core/src/lib/reed-solomon/decode_rs_ccsds.c b/gnuradio-core/src/lib/reed-solomon/decode_rs_ccsds.c
new file mode 100644
index 0000000000..2543d3a640
--- /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 0000000000..9d56d0bf11
--- /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
+ 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 0000000000..a748b34689
--- /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 0000000000..91d43e1572
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/exercise.c
@@ -0,0 +1,126 @@
+/* Exercise an RS codec a specified number of times using random
+ * data and error patterns
+ *
+ * Copyright 2002 Phil Karn, KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+#define FLAG_ERASURE 1 /* Randomly flag 50% of errors as erasures */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef FIXED
+#include "fixed.h"
+#define EXERCISE exercise_8
+#elif defined(CCSDS)
+#include "fixed.h"
+#include "ccsds.h"
+#define EXERCISE exercise_ccsds
+#elif defined(BIGSYM)
+#include "int.h"
+#define EXERCISE exercise_int
+#else
+#include "char.h"
+#define EXERCISE exercise_char
+#endif
+
+#ifdef FIXED
+#define PRINTPARM printf("(255,223):");
+#elif defined(CCSDS)
+#define PRINTPARM printf("CCSDS (255,223):");
+#else
+#define PRINTPARM printf("(%d,%d):",rs->nn,rs->nn-rs->nroots);
+#endif
+
+/* Exercise the RS codec passed as an argument */
+int EXERCISE(
+#if !defined(CCSDS) && !defined(FIXED)
+void *p,
+#endif
+int trials){
+#if !defined(CCSDS) && !defined(FIXED)
+ struct rs *rs = (struct rs *)p;
+#endif
+ DTYPE block[NN],tblock[NN];
+ int i;
+ int errors;
+ int errlocs[NN];
+ int derrlocs[NROOTS];
+ int derrors;
+ int errval,errloc;
+ int erasures;
+ int decoder_errors = 0;
+
+ while(trials-- != 0){
+ /* Test up to the error correction capacity of the code */
+ for(errors=0;errors <= NROOTS/2;errors++){
+
+ /* Load block with random data and encode */
+ for(i=0;i<NN-NROOTS;i++)
+ block[i] = random() & NN;
+
+#if defined(CCSDS) || defined(FIXED)
+ ENCODE_RS(&block[0],&block[NN-NROOTS]);
+#else
+ ENCODE_RS(rs,&block[0],&block[NN-NROOTS]);
+#endif
+
+ /* Make temp copy, seed with errors */
+ memcpy(tblock,block,sizeof(tblock));
+ memset(errlocs,0,sizeof(errlocs));
+ memset(derrlocs,0,sizeof(derrlocs));
+ erasures=0;
+ for(i=0;i<errors;i++){
+ do {
+ errval = random() & NN;
+ } while(errval == 0); /* Error value must be nonzero */
+
+ do {
+ errloc = random() % NN;
+ } while(errlocs[errloc] != 0); /* Must not choose the same location twice */
+
+ errlocs[errloc] = 1;
+
+#if FLAG_ERASURE
+ if(random() & 1) /* 50-50 chance */
+ derrlocs[erasures++] = errloc;
+#endif
+ tblock[errloc] ^= errval;
+ }
+
+ /* Decode the errored block */
+#if defined(CCSDS) || defined(FIXED)
+ derrors = DECODE_RS(tblock,derrlocs,erasures);
+#else
+ derrors = DECODE_RS(rs,tblock,derrlocs,erasures);
+#endif
+
+ if(derrors != errors){
+ PRINTPARM
+ printf(" decoder says %d errors, true number is %d\n",derrors,errors);
+ decoder_errors++;
+ }
+ for(i=0;i<derrors;i++){
+ if(errlocs[derrlocs[i]] == 0){
+ PRINTPARM
+ printf(" decoder indicates error in location %d without error\n",i);
+ decoder_errors++;
+ }
+ }
+ if(memcmp(tblock,block,sizeof(tblock)) != 0){
+ PRINTPARM
+ printf(" uncorrected errors! output ^ input:");
+ decoder_errors++;
+ for(i=0;i<NN;i++)
+ printf(" %02x",tblock[i] ^ block[i]);
+ printf("\n");
+ }
+ }
+ }
+ return decoder_errors;
+}
diff --git a/gnuradio-core/src/lib/reed-solomon/fixed.h b/gnuradio-core/src/lib/reed-solomon/fixed.h
new file mode 100644
index 0000000000..9f0ddd9a4d
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/fixed.h
@@ -0,0 +1,38 @@
+/* Configure the RS codec with fixed parameters for CCSDS standard
+ * (255,223) code over GF(256). Note: the conventional basis is still
+ * used; the dual-basis mappings are performed in [en|de]code_rs_ccsds.c
+ *
+ * Copyright 2002 Phil Karn, KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+#define DTYPE unsigned char
+
+static inline int mod255(int x){
+ while (x >= 255) {
+ x -= 255;
+ x = (x >> 8) + (x & 255);
+ }
+ return x;
+}
+#define MODNN(x) mod255(x)
+
+extern unsigned char CCSDS_alpha_to[];
+extern unsigned char CCSDS_index_of[];
+extern unsigned char CCSDS_poly[];
+
+#define MM 8
+#define NN 255
+#define ALPHA_TO CCSDS_alpha_to
+#define INDEX_OF CCSDS_index_of
+#define GENPOLY CCSDS_poly
+#define NROOTS 32
+#define FCR 112
+#define PRIM 11
+#define IPRIM 116
+#define A0 (NN)
+
+#define ENCODE_RS encode_rs_8
+#define DECODE_RS decode_rs_8
+
+void ENCODE_RS(DTYPE *data,DTYPE *parity);
+int DECODE_RS(DTYPE *data, int *eras_pos, int no_eras);
diff --git a/gnuradio-core/src/lib/reed-solomon/gen_ccsds.c b/gnuradio-core/src/lib/reed-solomon/gen_ccsds.c
new file mode 100644
index 0000000000..1e4e4f5363
--- /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 0000000000..9dde18917b
--- /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 0000000000..11d7c81707
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/init_rs.c
@@ -0,0 +1,128 @@
+/* Initialize a RS codec
+ *
+ * Copyright 2002 Phil Karn, KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+#include <stdlib.h>
+
+#ifdef CCSDS
+#include "ccsds.h"
+#elif defined(BIGSYM)
+#include "int.h"
+#else
+#include "char.h"
+#endif
+
+#define NULL ((void *)0)
+
+void FREE_RS(void *p){
+ struct rs *rs = (struct rs *)p;
+
+ free(rs->alpha_to);
+ free(rs->index_of);
+ free(rs->genpoly);
+ free(rs);
+}
+
+/* Initialize a Reed-Solomon codec
+ * symsize = symbol size, bits (1-8)
+ * gfpoly = Field generator polynomial coefficients
+ * fcr = first root of RS code generator polynomial, index form
+ * prim = primitive element to generate polynomial roots
+ * nroots = RS code generator polynomial degree (number of roots)
+ */
+void *INIT_RS(unsigned int symsize,unsigned int gfpoly,unsigned fcr,unsigned prim,
+ unsigned int nroots){
+ struct rs *rs;
+ int i, j, sr,root,iprim;
+
+ if(symsize > 8*sizeof(DTYPE))
+ return NULL; /* Need version with ints rather than chars */
+
+ if(fcr >= (1<<symsize))
+ return NULL;
+ if(prim == 0 || prim >= (1<<symsize))
+ return NULL;
+ if(nroots >= (1<<symsize))
+ return NULL; /* Can't have more roots than symbol values! */
+
+ rs = (struct rs *)calloc(1,sizeof(struct rs));
+ rs->mm = symsize;
+ rs->nn = (1<<symsize)-1;
+
+ rs->alpha_to = (DTYPE *)malloc(sizeof(DTYPE)*(rs->nn+1));
+ if(rs->alpha_to == NULL){
+ free(rs);
+ return NULL;
+ }
+ rs->index_of = (DTYPE *)malloc(sizeof(DTYPE)*(rs->nn+1));
+ if(rs->index_of == NULL){
+ free(rs->alpha_to);
+ free(rs);
+ return NULL;
+ }
+
+ /* Generate Galois field lookup tables */
+ rs->index_of[0] = A0; /* log(zero) = -inf */
+ rs->alpha_to[A0] = 0; /* alpha**-inf = 0 */
+ sr = 1;
+ for(i=0;i<rs->nn;i++){
+ rs->index_of[sr] = i;
+ rs->alpha_to[i] = sr;
+ sr <<= 1;
+ if(sr & (1<<symsize))
+ sr ^= gfpoly;
+ sr &= rs->nn;
+ }
+ if(sr != 1){
+ /* field generator polynomial is not primitive! */
+ free(rs->alpha_to);
+ free(rs->index_of);
+ free(rs);
+ return NULL;
+ }
+
+ /* Form RS code generator polynomial from its roots */
+ rs->genpoly = (DTYPE *)malloc(sizeof(DTYPE)*(nroots+1));
+ if(rs->genpoly == NULL){
+ free(rs->alpha_to);
+ free(rs->index_of);
+ free(rs);
+ return NULL;
+ }
+ rs->fcr = fcr;
+ rs->prim = prim;
+ rs->nroots = nroots;
+
+ /* Find prim-th root of 1, used in decoding */
+ for(iprim=1;(iprim % prim) != 0;iprim += rs->nn)
+ ;
+ rs->iprim = iprim / prim;
+
+ rs->genpoly[0] = 1;
+ for (i = 0,root=fcr*prim; i < nroots; i++,root += prim) {
+ rs->genpoly[i+1] = 1;
+
+ /* Multiply rs->genpoly[] by @**(root + x) */
+ for (j = i; j > 0; j--){
+ if (rs->genpoly[j] != 0)
+ rs->genpoly[j] = rs->genpoly[j-1] ^ rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[j]] + root)];
+ else
+ rs->genpoly[j] = rs->genpoly[j-1];
+ }
+ /* rs->genpoly[0] can never be zero */
+ rs->genpoly[0] = rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[0]] + root)];
+ }
+ /* convert rs->genpoly[] to index form for quicker encoding */
+ for (i = 0; i <= nroots; i++)
+ rs->genpoly[i] = rs->index_of[rs->genpoly[i]];
+
+#if 0
+ printf ("genpoly:\n");
+ for (i = nroots; i >= 0; i--){
+ printf (" %3d*X^%d\n", rs->alpha_to[rs->genpoly[i]], i);
+ }
+#endif
+
+ return rs;
+}
diff --git a/gnuradio-core/src/lib/reed-solomon/int.h b/gnuradio-core/src/lib/reed-solomon/int.h
new file mode 100644
index 0000000000..2b0405ae02
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/int.h
@@ -0,0 +1,54 @@
+/* Include file to configure the RS codec for integer symbols
+ *
+ * Copyright 2002, Phil Karn, KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+#define DTYPE int
+
+/* Reed-Solomon codec control block */
+struct rs {
+ unsigned int mm; /* Bits per symbol */
+ unsigned int nn; /* Symbols per block (= (1<<mm)-1) */
+ int *alpha_to; /* log lookup table */
+ int *index_of; /* Antilog lookup table */
+ int *genpoly; /* Generator polynomial */
+ unsigned int nroots; /* Number of generator roots = number of parity symbols */
+ unsigned int fcr; /* First consecutive root, index form */
+ unsigned int prim; /* Primitive element, index form */
+ unsigned int iprim; /* prim-th root of 1, index form */
+};
+
+static inline int modnn(struct rs *rs,int x){
+ while (x >= rs->nn) {
+ x -= rs->nn;
+ x = (x >> rs->mm) + (x & rs->nn);
+ }
+ return x;
+}
+#define MODNN(x) modnn(rs,x)
+
+#define MM (rs->mm)
+#define NN (rs->nn)
+#define ALPHA_TO (rs->alpha_to)
+#define INDEX_OF (rs->index_of)
+#define GENPOLY (rs->genpoly)
+#define NROOTS (rs->nroots)
+#define FCR (rs->fcr)
+#define PRIM (rs->prim)
+#define IPRIM (rs->iprim)
+#define A0 (NN)
+
+#define ENCODE_RS encode_rs_int
+#define DECODE_RS decode_rs_int
+#define INIT_RS init_rs_int
+#define FREE_RS free_rs_int
+
+void ENCODE_RS(void *p,DTYPE *data,DTYPE *parity);
+int DECODE_RS(void *p,DTYPE *data,int *eras_pos,int no_eras);
+void *INIT_RS(unsigned int symsize,unsigned int gfpoly,unsigned int fcr,
+ unsigned int prim,unsigned int nroots);
+void FREE_RS(void *p);
+
+
+
+
diff --git a/gnuradio-core/src/lib/reed-solomon/rs.3 b/gnuradio-core/src/lib/reed-solomon/rs.3
new file mode 100644
index 0000000000..c3953ce57a
--- /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 0000000000..9e731d9d92
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/rs.h
@@ -0,0 +1,30 @@
+/* User include file for the Reed-Solomon codec
+ * Copyright 2002, Phil Karn KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+
+/* General purpose RS codec, 8-bit symbols */
+void encode_rs_char(void *rs,unsigned char *data,unsigned char *parity);
+int decode_rs_char(void *rs,unsigned char *data,int *eras_pos,
+ int no_eras);
+void *init_rs_char(unsigned int symsize,unsigned int gfpoly,
+ unsigned int fcr,unsigned int prim,unsigned int nroots);
+void free_rs_char(void *rs);
+
+/* General purpose RS codec, integer symbols */
+void encode_rs_int(void *rs,int *data,int *parity);
+int decode_rs_int(void *rs,int *data,int *eras_pos,int no_eras);
+void *init_rs_int(unsigned int symsize,unsigned int gfpoly,unsigned int fcr,
+ unsigned int prim,unsigned int nroots);
+void free_rs_int(void *rs);
+
+/* CCSDS standard (255,223) RS codec with conventional (*not* dual-basis)
+ * symbol representation
+ */
+void encode_rs_8(unsigned char *data,unsigned char *parity);
+int decode_rs_8(unsigned char *data,int *eras_pos,int no_eras);
+
+/* Tables to map from conventional->dual (Taltab) and
+ * dual->conventional (Tal1tab) bases
+ */
+extern unsigned char Taltab[],Tal1tab[];
diff --git a/gnuradio-core/src/lib/reed-solomon/rstest.c b/gnuradio-core/src/lib/reed-solomon/rstest.c
new file mode 100644
index 0000000000..d8fc5448a7
--- /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/Makefile.am b/gnuradio-core/src/lib/runtime/Makefile.am
new file mode 100644
index 0000000000..7ee94ba1b8
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/Makefile.am
@@ -0,0 +1,109 @@
+#
+# Copyright 2003,2004 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+include $(top_srcdir)/Makefile.common
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(CPPUNIT_INCLUDES)
+
+noinst_LTLIBRARIES = libruntime.la libruntime-qa.la
+
+libruntime_la_LIBADD = \
+ $(SHM_OPEN_LIBS)
+
+
+libruntime_la_SOURCES = \
+ gr_block.cc \
+ gr_block_detail.cc \
+ gr_buffer.cc \
+ gr_dispatcher.cc \
+ gr_error_handler.cc \
+ gr_io_signature.cc \
+ gr_local_sighandler.cc \
+ gr_message.cc \
+ gr_msg_handler.cc \
+ gr_msg_queue.cc \
+ gr_pagesize.cc \
+ gr_preferences.cc \
+ gr_realtime.cc \
+ gr_single_threaded_scheduler.cc \
+ gr_tmp_path.cc \
+ gr_vmcircbuf.cc \
+ gr_vmcircbuf_mmap_shm_open.cc \
+ gr_vmcircbuf_mmap_tmpfile.cc \
+ gr_vmcircbuf_createfilemapping.cc \
+ gr_vmcircbuf_sysv_shm.cc \
+ gr_select_handler.cc
+
+libruntime_qa_la_SOURCES = \
+ qa_gr_block.cc \
+ qa_gr_buffer.cc \
+ qa_gr_io_signature.cc \
+ qa_gr_vmcircbuf.cc \
+ qa_runtime.cc
+
+grinclude_HEADERS = \
+ gr_block.h \
+ gr_block_detail.h \
+ gr_buffer.h \
+ gr_complex.h \
+ gr_dispatcher.h \
+ gr_error_handler.h \
+ gr_io_signature.h \
+ gr_local_sighandler.h \
+ gr_message.h \
+ gr_msg_handler.h \
+ gr_msg_queue.h \
+ gr_pagesize.h \
+ gr_preferences.h \
+ gr_realtime.h \
+ gr_runtime.h \
+ gr_select_handler.h \
+ gr_single_threaded_scheduler.h \
+ gr_timer.h \
+ gr_tmp_path.h \
+ gr_types.h \
+ gr_vmcircbuf.h
+
+noinst_HEADERS = \
+ gr_vmcircbuf_mmap_shm_open.h \
+ gr_vmcircbuf_mmap_tmpfile.h \
+ gr_vmcircbuf_sysv_shm.h \
+ gr_vmcircbuf_createfilemapping.h \
+ qa_gr_block.h \
+ qa_gr_buffer.h \
+ qa_gr_io_signature.h \
+ qa_gr_vmcircbuf.h \
+ qa_runtime.h
+
+swiginclude_HEADERS = \
+ gr_block.i \
+ gr_block_detail.i \
+ gr_buffer.i \
+ gr_dispatcher.i \
+ gr_error_handler.i \
+ gr_io_signature.i \
+ gr_message.i \
+ gr_msg_handler.i \
+ gr_msg_queue.i \
+ gr_realtime.i \
+ gr_single_threaded_scheduler.i \
+ gr_swig_block_magic.i \
+ runtime.i
diff --git a/gnuradio-core/src/lib/runtime/gr_block.cc b/gnuradio-core/src/lib/runtime/gr_block.cc
new file mode 100644
index 0000000000..8378c8f7de
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_block.cc
@@ -0,0 +1,131 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_block.h>
+#include <gr_block_detail.h>
+#include <stdexcept>
+
+static long s_next_id = 0;
+static long s_ncurrently_allocated = 0;
+
+long
+gr_block_ncurrently_allocated ()
+{
+ return s_ncurrently_allocated;
+}
+
+gr_block::gr_block (const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature)
+ : d_name (name),
+ d_input_signature (input_signature),
+ d_output_signature (output_signature),
+ d_output_multiple (1),
+ d_relative_rate (1.0),
+ d_unique_id (s_next_id++),
+ d_history(1),
+ d_fixed_rate(false)
+{
+ s_ncurrently_allocated++;
+}
+
+gr_block::~gr_block ()
+{
+ s_ncurrently_allocated--;
+}
+
+// stub implementation: 1:1
+
+void
+gr_block::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+ unsigned ninputs = ninput_items_required.size ();
+ for (unsigned i = 0; i < ninputs; i++)
+ ninput_items_required[i] = noutput_items;
+}
+
+// default implementation
+
+bool
+gr_block::check_topology (int ninputs, int noutputs)
+{
+ return true;
+}
+
+bool
+gr_block::start()
+{
+ return true;
+}
+
+bool
+gr_block::stop()
+{
+ return true;
+}
+
+void
+gr_block::set_output_multiple (int multiple)
+{
+ if (multiple < 1)
+ throw std::invalid_argument ("gr_block::set_output_multiple");
+
+ d_output_multiple = multiple;
+}
+
+void
+gr_block::set_relative_rate (double relative_rate)
+{
+ if (relative_rate < 0.0)
+ throw std::invalid_argument ("gr_block::set_relative_rate");
+
+ d_relative_rate = relative_rate;
+}
+
+
+void
+gr_block::consume (int which_input, int how_many_items)
+{
+ d_detail->consume (which_input, how_many_items);
+}
+
+void
+gr_block::consume_each (int how_many_items)
+{
+ d_detail->consume_each (how_many_items);
+}
+
+int
+gr_block::fixed_rate_ninput_to_noutput(int ninput)
+{
+ throw std::runtime_error("Unimplemented");
+}
+
+int
+gr_block::fixed_rate_noutput_to_ninput(int noutput)
+{
+ throw std::runtime_error("Unimplemented");
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_block.h b/gnuradio-core/src/lib/runtime/gr_block.h
new file mode 100644
index 0000000000..df72e1a3fd
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_block.h
@@ -0,0 +1,247 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_BLOCK_H
+#define INCLUDED_GR_BLOCK_H
+
+#include <gr_runtime.h>
+#include <string>
+
+/*!
+ * \brief The abstract base class for all signal processing blocks.
+ * \ingroup block
+ *
+ * Blocks have a set of input streams and output streams. The
+ * input_signature and output_signature define the number of input
+ * streams and output streams respectively, and the type of the data
+ * items in each stream.
+ *
+ * Although blocks may consume data on each input stream at a
+ * different rate, all outputs streams must produce data at the same
+ * rate. That rate may be different from any of the input rates.
+ *
+ * User derived blocks override two methods, forecast and general_work,
+ * to implement their signal processing behavior. forecast is called
+ * by the system scheduler to determine how many items are required on
+ * each input stream in order to produce a given number of output
+ * items.
+ *
+ * general_work is called to perform the signal processing in the block.
+ * It reads the input items and writes the output items.
+ */
+
+class gr_block {
+
+ public:
+
+ virtual ~gr_block ();
+
+ std::string name () const { return d_name; }
+ gr_io_signature_sptr input_signature () const { return d_input_signature; }
+ gr_io_signature_sptr output_signature () const { return d_output_signature; }
+ long unique_id () const { return d_unique_id; }
+
+ /*!
+ * Assume block computes y_i = f(x_i, x_i-1, x_i-2, x_i-3...)
+ * History is the number of x_i's that are examined to produce one y_i.
+ * This comes in handy for FIR filters, where we use history to
+ * ensure that our input contains the appropriate "history" for the
+ * filter. History should be equal to the number of filter taps.
+ */
+ unsigned history () const { return d_history; }
+ void set_history (unsigned history) { d_history = history; }
+
+ /*!
+ * \brief return true if this block has a fixed input to output rate
+ *
+ * If true, then fixed_rate_in_to_out and fixed_rate_out_to_in may be called.
+ */
+ bool fixed_rate() const { return d_fixed_rate; }
+
+ // ----------------------------------------------------------------
+ // override these to define your behavior
+ // ----------------------------------------------------------------
+
+ /*!
+ * \brief Estimate input requirements given output request
+ *
+ * \param noutput_items number of output items to produce
+ * \param ninput_items_required number of input items required on each input stream
+ *
+ * Given a request to product \p noutput_items, estimate the number of
+ * data items required on each input stream. The estimate doesn't have
+ * to be exact, but should be close.
+ */
+ virtual void forecast (int noutput_items,
+ gr_vector_int &ninput_items_required);
+
+ /*!
+ * \brief compute output items from input items
+ *
+ * \param noutput_items number of output items to write on each output stream
+ * \param ninput_items number of input items available on each input stream
+ * \param input_items vector of pointers to the input items, one entry per input stream
+ * \param output_items vector of pointers to the output items, one entry per output stream
+ *
+ * \returns number of items actually written to each output stream, or -1 on EOF.
+ * It is OK to return a value less than noutput_items. -1 <= return value <= noutput_items
+ *
+ * general_work must call consume or consume_each to indicate how many items
+ * were consumed on each input stream.
+ */
+ virtual int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items) = 0;
+
+ /*!
+ * \brief Confirm that ninputs and noutputs is an acceptable combination.
+ *
+ * \param ninputs number of input streams connected
+ * \param noutputs number of output streams connected
+ *
+ * \returns true if this is a valid configuration for this block.
+ *
+ * This function is called by the runtime system whenever the
+ * topology changes. Most classes do not need to override this.
+ * This check is in addition to the constraints specified by the input
+ * and output gr_io_signatures.
+ */
+ virtual bool check_topology (int ninputs, int noutputs);
+
+ /*!
+ * \brief Called to enable drivers, etc for i/o devices.
+ *
+ * This allows a block to enable an associated driver to begin
+ * transfering data just before we start to execute the scheduler.
+ * The end result is that this reduces latency in the pipeline when
+ * dealing with audio devices, usrps, etc.
+ */
+ virtual bool start();
+
+ /*!
+ * \brief Called to disable drivers, etc for i/o devices.
+ */
+ virtual bool stop();
+
+ // ----------------------------------------------------------------
+
+ /*!
+ * \brief Constrain the noutput_items argument passed to forecast and general_work
+ *
+ * set_output_multiple causes the scheduler to ensure that the noutput_items
+ * argument passed to forecast and general_work will be an integer multiple
+ * of \param multiple The default value of output multiple is 1.
+ */
+ void set_output_multiple (int multiple);
+ int output_multiple () const { return d_output_multiple; }
+
+ /*!
+ * \brief Tell the scheduler \p how_many_items of input stream \p which_input were consumed.
+ */
+ void consume (int which_input, int how_many_items);
+
+ /*!
+ * \brief Tell the scheduler \p how_many_items were consumed on each input stream.
+ */
+ void consume_each (int how_many_items);
+
+ /*!
+ * \brief Set the approximate output rate / input rate
+ *
+ * Provide a hint to the buffer allocator and scheduler.
+ * The default relative_rate is 1.0
+ *
+ * decimators have relative_rates < 1.0
+ * interpolators have relative_rates > 1.0
+ */
+ void set_relative_rate (double relative_rate);
+
+ /*!
+ * \brief return the approximate output rate / input rate
+ */
+ double relative_rate () const { return d_relative_rate; }
+
+ /*
+ * The following two methods provide special case info to the
+ * scheduler in the event that a block has a fixed input to output
+ * ratio. gr_sync_block, gr_sync_decimator and gr_sync_interpolator
+ * override these. If you're fixed rate, subclass one of those.
+ */
+ /*!
+ * \brief Given ninput samples, return number of output samples that will be produced.
+ * N.B. this is only defined if fixed_rate returns true.
+ * Generally speaking, you don't need to override this.
+ */
+ virtual int fixed_rate_ninput_to_noutput(int ninput);
+
+ /*!
+ * \brief Given noutput samples, return number of input samples required to produce noutput.
+ * N.B. this is only defined if fixed_rate returns true.
+ * Generally speaking, you don't need to override this.
+ */
+ virtual int fixed_rate_noutput_to_ninput(int noutput);
+
+ // ----------------------------------------------------------------------------
+
+ private:
+
+ std::string d_name;
+ gr_io_signature_sptr d_input_signature;
+ gr_io_signature_sptr d_output_signature;
+ int d_output_multiple;
+ double d_relative_rate; // approx output_rate / input_rate
+ gr_block_detail_sptr d_detail; // implementation details
+ long d_unique_id; // convenient for debugging
+ unsigned d_history;
+ bool d_fixed_rate;
+
+
+ protected:
+
+ gr_block (const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature);
+
+ //! may only be called during constructor
+ void set_input_signature (gr_io_signature_sptr iosig){
+ d_input_signature = iosig;
+ }
+
+ //! may only be called during constructor
+ void set_output_signature (gr_io_signature_sptr iosig){
+ d_output_signature = iosig;
+ }
+
+ void set_fixed_rate(bool fixed_rate){ d_fixed_rate = fixed_rate; }
+
+ // These are really only for internal use, but leaving them public avoids
+ // having to work up an ever-varying list of friends
+
+ public:
+ gr_block_detail_sptr detail () const { return d_detail; }
+ void set_detail (gr_block_detail_sptr detail) { d_detail = detail; }
+};
+
+long gr_block_ncurrently_allocated ();
+
+#endif /* INCLUDED_GR_BLOCK_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_block.i b/gnuradio-core/src/lib/runtime/gr_block.i
new file mode 100644
index 0000000000..f1f0332e85
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_block.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+class gr_block;
+typedef boost::shared_ptr<gr_block> gr_block_sptr;
+%template(gr_block_sptr) boost::shared_ptr<gr_block>;
+
+// support vectors of these...
+namespace std {
+ %template(x_vector_gr_block_sptr) vector<gr_block_sptr>;
+};
+
+class gr_block {
+ protected:
+ gr_block (const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature);
+
+ public:
+
+ virtual ~gr_block ();
+
+ std::string name () const;
+ gr_io_signature_sptr input_signature () const;
+ gr_io_signature_sptr output_signature () const;
+ long unique_id () const;
+ unsigned history () const;
+
+ int output_multiple () const;
+ double relative_rate () const;
+
+ bool check_topology (int ninputs, int noutputs);
+ bool start();
+ bool stop();
+
+ // internal use
+ gr_block_detail_sptr detail () const { return d_detail; }
+ void set_detail (gr_block_detail_sptr detail) { d_detail = detail; }
+};
+
+%rename(block_ncurrently_allocated) gr_block_ncurrently_allocated;
+long gr_block_ncurrently_allocated ();
+
+%pythoncode %{
+gr_block_sptr.__repr__ = lambda self: "<gr_block %s (%d)>" % (self.name(), self.unique_id ())
+gr_block_sptr.block = lambda self: self
+%}
diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.cc b/gnuradio-core/src/lib/runtime/gr_block_detail.cc
new file mode 100644
index 0000000000..0ad5da49ce
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_block_detail.cc
@@ -0,0 +1,108 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_block_detail.h>
+#include <gr_buffer.h>
+
+static long s_ncurrently_allocated = 0;
+
+long
+gr_block_detail_ncurrently_allocated ()
+{
+ return s_ncurrently_allocated;
+}
+
+gr_block_detail::gr_block_detail (unsigned int ninputs, unsigned int noutputs)
+ : d_ninputs (ninputs), d_noutputs (noutputs),
+ d_input (ninputs), d_output (noutputs),
+ d_done (false)
+{
+ s_ncurrently_allocated++;
+}
+
+gr_block_detail::~gr_block_detail ()
+{
+ // should take care of itself
+ s_ncurrently_allocated--;
+}
+
+void
+gr_block_detail::set_input (unsigned int which, gr_buffer_reader_sptr reader)
+{
+ if (which >= d_ninputs)
+ throw std::invalid_argument ("gr_block_detail::set_input");
+
+ d_input[which] = reader;
+}
+
+void
+gr_block_detail::set_output (unsigned int which, gr_buffer_sptr buffer)
+{
+ if (which >= d_noutputs)
+ throw std::invalid_argument ("gr_block_detail::set_output");
+
+ d_output[which] = buffer;
+}
+
+gr_block_detail_sptr
+gr_make_block_detail (unsigned int ninputs, unsigned int noutputs)
+{
+ return gr_block_detail_sptr (new gr_block_detail (ninputs, noutputs));
+}
+
+void
+gr_block_detail::set_done (bool done)
+{
+ d_done = done;
+ for (unsigned int i = 0; i < d_noutputs; i++)
+ d_output[i]->set_done (done);
+
+ for (unsigned int i = 0; i < d_ninputs; i++)
+ d_input[i]->set_done (done);
+}
+
+void
+gr_block_detail::consume (int which_input, int how_many_items)
+{
+ if (how_many_items > 0)
+ input (which_input)->update_read_pointer (how_many_items);
+}
+
+void
+gr_block_detail::consume_each (int how_many_items)
+{
+ if (how_many_items > 0)
+ for (int i = 0; i < ninputs (); i++)
+ d_input[i]->update_read_pointer (how_many_items);
+}
+
+void
+gr_block_detail::produce_each (int how_many_items)
+{
+ if (how_many_items > 0)
+ for (int i = 0; i < noutputs (); i++)
+ d_output[i]->update_write_pointer (how_many_items);
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.h b/gnuradio-core/src/lib/runtime/gr_block_detail.h
new file mode 100644
index 0000000000..90c912c25a
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_block_detail.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more detail.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_BLOCK_DETAIL_H
+#define INCLUDED_GR_BLOCK_DETAIL_H
+
+#include <gr_runtime.h>
+#include <stdexcept>
+
+/*!
+ * \brief Implementation details to support the signal processing abstraction
+ * \ingroup internal
+ *
+ * This class contains implementation detail that should be "out of sight"
+ * of almost all users of GNU Radio. This decoupling also means that
+ * we can make changes to the guts without having to recompile everything.
+ */
+
+class gr_block_detail {
+ public:
+ ~gr_block_detail ();
+
+ int ninputs () const { return d_ninputs; }
+ int noutputs () const { return d_noutputs; }
+ bool sink_p () const { return d_noutputs == 0; }
+ bool source_p () const { return d_ninputs == 0; }
+
+ void set_done (bool done);
+ bool done () const { return d_done; }
+
+ void set_input (unsigned int which, gr_buffer_reader_sptr reader);
+ gr_buffer_reader_sptr input (unsigned int which)
+ {
+ if (which >= d_ninputs)
+ throw std::invalid_argument ("gr_block_detail::input");
+ return d_input[which];
+ }
+
+ void set_output (unsigned int which, gr_buffer_sptr buffer);
+ gr_buffer_sptr output (unsigned int which)
+ {
+ if (which >= d_noutputs)
+ throw std::invalid_argument ("gr_block_detail::output");
+ return d_output[which];
+ }
+
+ /*!
+ * \brief Tell the scheduler \p how_many_items of input stream \p which_input were consumed.
+ */
+ void consume (int which_input, int how_many_items);
+
+ /*!
+ * \brief Tell the scheduler \p how_many_items were consumed on each input stream.
+ */
+ void consume_each (int how_many_items);
+
+ void produce_each (int how_many_items);
+
+ // ----------------------------------------------------------------------------
+
+ private:
+ unsigned int d_ninputs;
+ unsigned int d_noutputs;
+ std::vector<gr_buffer_reader_sptr> d_input;
+ std::vector<gr_buffer_sptr> d_output;
+ bool d_done;
+
+ gr_block_detail (unsigned int ninputs, unsigned int noutputs);
+
+ friend gr_block_detail_sptr
+ gr_make_block_detail (unsigned int ninputs, unsigned int noutputs);
+};
+
+gr_block_detail_sptr
+gr_make_block_detail (unsigned int ninputs, unsigned int noutputs);
+
+long
+gr_block_detail_ncurrently_allocated ();
+
+#endif /* INCLUDED_GR_BLOCK_DETAIL_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.i b/gnuradio-core/src/lib/runtime/gr_block_detail.i
new file mode 100644
index 0000000000..9d3843ebe7
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+class gr_block_detail;
+typedef boost::shared_ptr<gr_block_detail> gr_block_detail_sptr;
+%template(gr_block_detail_sptr) boost::shared_ptr<gr_block_detail>;
+%rename(block_detail) gr_make_block_detail;
+%ignore gr_block_detail;
+
+gr_block_detail_sptr gr_make_block_detail (unsigned int ninputs, unsigned int noutputs);
+
+class gr_block_detail {
+ public:
+
+ ~gr_block_detail ();
+
+ int ninputs () const { return d_ninputs; }
+ int noutputs () const { return d_noutputs; }
+ bool sink_p () const { return d_noutputs == 0; }
+ bool source_p () const { return d_ninputs == 0; }
+
+ void set_input (unsigned int which, gr_buffer_reader_sptr reader);
+ gr_buffer_reader_sptr input (unsigned int which)
+ {
+ if (which >= d_ninputs)
+ throw std::invalid_argument ("gr_block_detail::input");
+ return d_input[which];
+ }
+
+ void set_output (unsigned int which, gr_buffer_sptr buffer);
+ gr_buffer_sptr output (unsigned int which)
+ {
+ if (which >= d_noutputs)
+ throw std::invalid_argument ("gr_block_detail::output");
+ return d_output[which];
+ }
+
+ // ----------------------------------------------------------------------------
+
+ private:
+ gr_block_detail (unsigned int ninputs, unsigned int noutputs);
+
+};
+
+
+%rename(block_detail_ncurrently_allocated) gr_block_detail_ncurrently_allocated;
+long gr_block_detail_ncurrently_allocated ();
diff --git a/gnuradio-core/src/lib/runtime/gr_buffer.cc b/gnuradio-core/src/lib/runtime/gr_buffer.cc
new file mode 100644
index 0000000000..d3d1230967
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_buffer.cc
@@ -0,0 +1,248 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_buffer.h>
+#include <gr_vmcircbuf.h>
+#include <gr_math.h>
+#include <stdexcept>
+#include <iostream>
+#include <assert.h>
+#include <algorithm>
+
+static long s_buffer_count = 0; // counts for debugging storage mgmt
+static long s_buffer_reader_count = 0;
+
+// ----------------------------------------------------------------------------
+// Notes on storage management
+//
+// Pretty much all the fundamental classes are now using the
+// shared_ptr stuff for automatic reference counting. To ensure that
+// no mistakes are made, we make the constructors for classes private,
+// and then provide a free factory function that returns a smart
+// pointer to the desired class.
+//
+// gr_buffer and gr_buffer_reader are no exceptions. However, they
+// both want pointers to each other, and unless we do something, we'll
+// never delete any of them because of the circular structure.
+// They'll always have a reference count of at least one. We could
+// use boost::weak_ptr's from gr_buffer to gr_buffer_reader but that
+// introduces it's own problems. (gr_buffer_reader's destructor needs
+// to call gr_buffer::drop_reader, but has no easy way to get a
+// shared_ptr to itself.)
+//
+// Instead, we solve this problem by having gr_buffer hold a raw
+// pointer to gr_buffer_reader in its d_reader vector.
+// gr_buffer_reader's destructor calls gr_buffer::drop_reader, so
+// we're never left with an dangling pointer. gr_buffer_reader still
+// has a shared_ptr to the buffer ensuring that the buffer doesn't go
+// away under it. However, when the reference count of a
+// gr_buffer_reader goes to zero, we can successfully reclaim it.
+// ----------------------------------------------------------------------------
+
+
+/*
+ * Compute the minimum number of buffer items that work (i.e.,
+ * address space wrap-around works). To work is to satisfy this
+ * contraint for integer buffer_size and k:
+ *
+ * type_size * nitems == k * page_size
+ */
+static long
+minimum_buffer_items (long type_size, long page_size)
+{
+ return page_size / gr_gcd (type_size, page_size);
+}
+
+
+gr_buffer::gr_buffer (int nitems, size_t sizeof_item)
+ : d_base (0), d_bufsize (0), d_vmcircbuf (0),
+ d_sizeof_item (sizeof_item), d_write_index (0),
+ d_done (false)
+{
+ if (!allocate_buffer (nitems, sizeof_item))
+ throw std::bad_alloc ();
+
+ s_buffer_count++;
+}
+
+gr_buffer_sptr
+gr_make_buffer (int nitems, size_t sizeof_item)
+{
+ return gr_buffer_sptr (new gr_buffer (nitems, sizeof_item));
+}
+
+gr_buffer::~gr_buffer ()
+{
+ delete d_vmcircbuf;
+ assert (d_readers.size() == 0);
+ s_buffer_count--;
+}
+
+/*!
+ * sets d_vmcircbuf, d_base, d_bufsize.
+ * returns true iff successful.
+ */
+bool
+gr_buffer::allocate_buffer (int nitems, size_t sizeof_item)
+{
+ int orig_nitems = nitems;
+
+ // Any buffersize we come up with must be a multiple of min_nitems.
+
+ int granularity = gr_vmcircbuf_sysconfig::granularity ();
+ int min_nitems = minimum_buffer_items (sizeof_item, granularity);
+
+ // Round-up nitems to a multiple of min_nitems.
+
+ if (nitems % min_nitems != 0)
+ nitems = ((nitems / min_nitems) + 1) * min_nitems;
+
+ // If we rounded-up a whole bunch, give the user a heads up.
+ // This only happens if sizeof_item is not a power of two.
+
+ if (nitems > 2 * orig_nitems && nitems * (int) sizeof_item > granularity){
+ std::cerr << "gr_buffer::allocate_buffer: warning: tried to allocate\n"
+ << " " << orig_nitems << " items of size "
+ << sizeof_item << ". Due to alignment requirements\n"
+ << " " << nitems << " were allocated. If this isn't OK, consider padding\n"
+ << " your structure to a power-of-two bytes.\n"
+ << " On this platform, our allocation granularity is " << granularity << " bytes.\n";
+ }
+
+ d_bufsize = nitems;
+ d_vmcircbuf = gr_vmcircbuf_sysconfig::make (d_bufsize * d_sizeof_item);
+ if (d_vmcircbuf == 0){
+ std::cerr << "gr_buffer::allocate_buffer: failed to allocate buffer of size "
+ << d_bufsize * d_sizeof_item / 1024 << " KB\n";
+ return false;
+ }
+
+ d_base = (char *) d_vmcircbuf->pointer_to_first_copy ();
+ return true;
+}
+
+
+int
+gr_buffer::space_available () const
+{
+ if (d_readers.empty ())
+ return d_bufsize - 1; // See comment below
+
+ else {
+
+ // Find out the maximum amount of data available to our readers
+
+ int most_data = d_readers[0]->items_available ();
+ for (unsigned int i = 1; i < d_readers.size (); i++)
+ most_data = std::max (most_data, d_readers[i]->items_available ());
+
+ // The -1 ensures that the case d_write_index == d_read_index is
+ // unambiguous. It indicates that there is no data for the reader
+
+ return d_bufsize - most_data - 1;
+ }
+}
+
+void *
+gr_buffer::write_pointer ()
+{
+ return &d_base[d_write_index * d_sizeof_item];
+}
+
+void
+gr_buffer::update_write_pointer (int nitems)
+{
+ d_write_index = index_add (d_write_index, nitems);
+}
+
+gr_buffer_reader_sptr
+gr_buffer_add_reader (gr_buffer_sptr buf, int history)
+{
+ gr_buffer_reader_sptr r (new gr_buffer_reader (buf,
+ buf->index_sub(buf->d_write_index,
+ history-1)));
+ buf->d_readers.push_back (r.get ());
+
+ return r;
+}
+
+void
+gr_buffer::drop_reader (gr_buffer_reader *reader)
+{
+ // isn't C++ beautiful... GAG!
+
+ std::vector<gr_buffer_reader *>::iterator result =
+ std::find (d_readers.begin (), d_readers.end (), reader);
+
+ if (result == d_readers.end ())
+ throw std::invalid_argument ("gr_buffer::drop_reader"); // we didn't find it...
+
+ d_readers.erase (result);
+}
+
+long
+gr_buffer_ncurrently_allocated ()
+{
+ return s_buffer_count;
+}
+
+// ----------------------------------------------------------------------------
+
+gr_buffer_reader::gr_buffer_reader (gr_buffer_sptr buffer, unsigned int read_index)
+ : d_buffer (buffer), d_read_index (read_index)
+{
+ s_buffer_reader_count++;
+}
+
+gr_buffer_reader::~gr_buffer_reader ()
+{
+ d_buffer->drop_reader(this);
+ s_buffer_reader_count--;
+}
+
+int
+gr_buffer_reader::items_available () const
+{
+ return d_buffer->index_sub (d_buffer->d_write_index, d_read_index);
+}
+
+const void *
+gr_buffer_reader::read_pointer ()
+{
+ return &d_buffer->d_base[d_read_index * d_buffer->d_sizeof_item];
+}
+
+void
+gr_buffer_reader::update_read_pointer (int nitems)
+{
+ d_read_index = d_buffer->index_add (d_read_index, nitems);
+}
+
+long
+gr_buffer_reader_ncurrently_allocated ()
+{
+ return s_buffer_reader_count;
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_buffer.h b/gnuradio-core/src/lib/runtime/gr_buffer.h
new file mode 100644
index 0000000000..6f85f275ee
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_buffer.h
@@ -0,0 +1,196 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_BUFFER_H
+#define INCLUDED_GR_BUFFER_H
+
+#include <gr_runtime.h>
+
+class gr_vmcircbuf;
+
+/*!
+ * \brief Allocate a buffer that holds at least \p nitems of size \p sizeof_item.
+ *
+ * The total size of the buffer will be rounded up to a system
+ * dependent boundary. This is typically the system page size, but
+ * under MS windows is 64KB.
+ */
+gr_buffer_sptr gr_make_buffer (int nitems, size_t sizeof_item);
+
+
+/*!
+ * \brief Single writer, multiple reader fifo.
+ * \ingroup internal
+ */
+class gr_buffer {
+ public:
+ virtual ~gr_buffer ();
+
+ /*!
+ * \brief return number of items worth of space available for writing
+ */
+ int space_available () const;
+
+ /*!
+ * \brief return pointer to write buffer.
+ *
+ * The return value points at space that can hold at least
+ * space_available() items.
+ */
+ void *write_pointer ();
+
+ /*!
+ * \brief tell buffer that we wrote \p nitems into it
+ */
+ void update_write_pointer (int nitems);
+
+
+ void set_done (bool done) { d_done = done; }
+ bool done () const { return d_done; }
+
+ // -------------------------------------------------------------------------
+
+ private:
+
+ friend class gr_buffer_reader;
+ friend gr_buffer_sptr gr_make_buffer (int nitems, size_t sizeof_item);
+ friend gr_buffer_reader_sptr gr_buffer_add_reader (gr_buffer_sptr buf, int history);
+
+ protected:
+ char *d_base; // base address of buffer
+ unsigned int d_bufsize; // in items
+ private:
+ gr_vmcircbuf *d_vmcircbuf;
+ size_t d_sizeof_item; // in bytes
+ unsigned int d_write_index; // in items [0,d_bufsize)
+ std::vector<gr_buffer_reader *> d_readers;
+ bool d_done;
+
+ unsigned
+ index_add (unsigned a, unsigned b)
+ {
+ unsigned s = a + b;
+
+ if (s >= d_bufsize)
+ s -= d_bufsize;
+
+ assert (s < d_bufsize);
+ return s;
+ }
+
+ unsigned
+ index_sub (unsigned a, unsigned b)
+ {
+ int s = a - b;
+
+ if (s < 0)
+ s += d_bufsize;
+
+ assert ((unsigned) s < d_bufsize);
+ return s;
+ }
+
+ virtual bool allocate_buffer (int nitems, size_t sizeof_item);
+
+ /*!
+ * \brief constructor is private. Use gr_make_buffer to create instances.
+ *
+ * Allocate a buffer that holds at least \p nitems of size \p sizeof_item.
+ *
+ * The total size of the buffer will be rounded up to a system
+ * dependent boundary. This is typically the system page size, but
+ * under MS windows is 64KB.
+ */
+ gr_buffer (int nitems, size_t sizeof_item);
+
+ /*!
+ * \brief disassociate \p reader from this buffer
+ */
+ void drop_reader (gr_buffer_reader *reader);
+
+};
+
+//! create a new gr_buffer_reader and attach it to buffer \p buf
+gr_buffer_reader_sptr gr_buffer_add_reader (gr_buffer_sptr buf, int history);
+
+//! returns # of gr_buffers currently allocated
+long gr_buffer_ncurrently_allocated ();
+
+
+// ---------------------------------------------------------------------------
+
+/*!
+ * \brief How we keep track of the readers of a gr_buffer.
+ * \ingroup internal
+ */
+
+class gr_buffer_reader {
+
+ public:
+ ~gr_buffer_reader ();
+
+ /*!
+ * \brief Return number of items available for reading.
+ */
+ int items_available () const;
+
+ /*!
+ * \brief Return maximum number of items that could ever be available for reading.
+ * This is used as a sanity check in the scheduler to avoid looping forever.
+ */
+ int max_possible_items_available () const { return d_buffer->d_bufsize - 1; }
+
+ /*!
+ * \brief return pointer to read buffer.
+ *
+ * The return value points to items_available() number of items
+ */
+ const void *read_pointer ();
+
+ /*
+ * \brief tell buffer we read \p items from it
+ */
+ void update_read_pointer (int nitems);
+
+ void set_done (bool done) { d_buffer->set_done (done); }
+ bool done () const { return d_buffer->done (); }
+
+ // -------------------------------------------------------------------------
+
+ private:
+
+ friend class gr_buffer;
+ friend gr_buffer_reader_sptr gr_buffer_add_reader (gr_buffer_sptr buf, int history);
+
+
+ gr_buffer_sptr d_buffer;
+ unsigned int d_read_index; // in items [0,d->buffer.d_bufsize)
+
+ //! constructor is private. Use gr_buffer::add_reader to create instances
+ gr_buffer_reader (gr_buffer_sptr buffer, unsigned int read_index);
+};
+
+//! returns # of gr_buffer_readers currently allocated
+long gr_buffer_reader_ncurrently_allocated ();
+
+
+#endif /* INCLUDED_GR_BUFFER_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_buffer.i b/gnuradio-core/src/lib/runtime/gr_buffer.i
new file mode 100644
index 0000000000..80f92ece12
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+class gr_buffer;
+typedef boost::shared_ptr<gr_buffer> gr_buffer_sptr;
+%template(gr_buffer_sptr) boost::shared_ptr<gr_buffer>;
+%rename(buffer) gr_make_buffer;
+%ignore gr_buffer;
+
+gr_buffer_sptr gr_make_buffer (int nitems, size_t sizeof_item);
+
+class gr_buffer {
+ public:
+ ~gr_buffer ();
+
+ private:
+ gr_buffer (int nitems, size_t sizeof_item);
+};
+
+
+class gr_buffer_reader;
+typedef boost::shared_ptr<gr_buffer_reader> gr_buffer_reader_sptr;
+%template(gr_buffer_reader_sptr) boost::shared_ptr<gr_buffer_reader>;
+%ignore gr_buffer_reader;
+
+%rename(buffer_add_reader) gr_buffer_add_reader;
+gr_buffer_reader_sptr gr_buffer_add_reader (gr_buffer_sptr buf, int history);
+
+class gr_buffer_reader {
+ public:
+ ~gr_buffer_reader ();
+
+ private:
+ friend class gr_buffer;
+ gr_buffer_reader (gr_buffer_sptr buffer, unsigned int read_index);
+};
+
+
+%rename(buffer_ncurrently_allocated) gr_buffer_ncurrently_allocated;
+long gr_buffer_ncurrently_allocated ();
+
+%rename(buffer_reader_ncurrently_allocated) gr_buffer_reader_ncurrently_allocated;
+long gr_buffer_reader_ncurrently_allocated ();
+
diff --git a/gnuradio-core/src/lib/runtime/gr_complex.h b/gnuradio-core/src/lib/runtime/gr_complex.h
new file mode 100644
index 0000000000..242b2f54d4
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_COMPLEX_H
+#define INCLUDED_GR_COMPLEX_H
+
+#include <complex>
+typedef std::complex<float> gr_complex;
+typedef std::complex<double> gr_complexd;
+
+
+inline bool is_complex (gr_complex x) { return true;}
+inline bool is_complex (gr_complexd x) { return true;}
+inline bool is_complex (float x) { return false;}
+inline bool is_complex (double x) { return false;}
+inline bool is_complex (int x) { return false;}
+inline bool is_complex (char x) { return false;}
+inline bool is_complex (short x) { return false;}
+
+
+// this doesn't really belong here, but there are worse places for it...
+
+#define ASSERT_COMPLEXES_EQUAL(expected,actual,delta) \
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (expected.real(), actual.real(), delta); \
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (expected.imag(), actual.imag(), delta);
+
+#endif /* INCLUDED_GR_COMPLEX_H */
+
diff --git a/gnuradio-core/src/lib/runtime/gr_dispatcher.cc b/gnuradio-core/src/lib/runtime/gr_dispatcher.cc
new file mode 100644
index 0000000000..c2a1eb50af
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_dispatcher.cc
@@ -0,0 +1,192 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_dispatcher.h>
+#include <math.h>
+#include <errno.h>
+
+#ifdef HAVE_SELECT
+# ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+# else
+# ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+# endif
+# ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+# endif
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+# endif
+#endif
+
+
+static gr_dispatcher_sptr s_singleton;
+
+gr_dispatcher_sptr
+gr_make_dispatcher()
+{
+ return gr_dispatcher_sptr(new gr_dispatcher());
+}
+
+gr_dispatcher_sptr
+gr_dispatcher_singleton()
+{
+ if (s_singleton)
+ return s_singleton;
+
+ s_singleton = gr_make_dispatcher();
+ return s_singleton;
+}
+
+#if !defined(HAVE_SELECT) // Stub it out
+
+gr_dispatcher::gr_dispatcher()
+{
+}
+
+gr_dispatcher::~gr_dispatcher()
+{
+}
+
+bool
+gr_dispatcher::add_handler(gr_select_handler_sptr handler)
+{
+ return true;
+}
+
+bool
+gr_dispatcher::del_handler(gr_select_handler_sptr handler)
+{
+ return true;
+}
+
+bool
+gr_dispatcher::del_handler(gr_select_handler *handler)
+{
+ return true;
+}
+
+void
+gr_dispatcher::loop(double timeout)
+{
+}
+
+#else // defined(HAVE_SELECT)
+
+gr_dispatcher::gr_dispatcher()
+ : d_handler(FD_SETSIZE), d_max_index(-1)
+{
+}
+
+gr_dispatcher::~gr_dispatcher()
+{
+}
+
+bool
+gr_dispatcher::add_handler(gr_select_handler_sptr handler)
+{
+ int fd = handler->fd();
+ if (fd < 0 || fd >= FD_SETSIZE)
+ return false;
+
+ d_max_index = std::max(d_max_index, fd);
+ d_handler[fd] = handler;
+ return true;
+}
+
+bool
+gr_dispatcher::del_handler(gr_select_handler_sptr handler)
+{
+ return del_handler(handler.get());
+}
+
+bool
+gr_dispatcher::del_handler(gr_select_handler *handler)
+{
+ int fd = handler->fd();
+ if (fd < 0 || fd >= FD_SETSIZE)
+ return false;
+
+ d_handler[fd].reset();
+
+ if (fd == d_max_index){
+ int i;
+ for (i = fd - 1; i >= 0 && !d_handler[i]; i--)
+ ;
+ d_max_index = i;
+ }
+ return true;
+}
+
+
+void
+gr_dispatcher::loop(double timeout)
+{
+ struct timeval master;
+ struct timeval tmp;
+ fd_set rd_set;
+ fd_set wr_set;
+
+ double secs = floor (timeout);
+ master.tv_sec = (long) secs;
+ master.tv_usec = (long) ((timeout - secs) * 1e6);
+
+ while (d_max_index >= 0){
+ FD_ZERO(&rd_set);
+ FD_ZERO(&wr_set);
+
+ for (int i = 0; i <= d_max_index; i++){
+ if (d_handler[i] && d_handler[i]->readable())
+ FD_SET(i, &rd_set);
+ if (d_handler[i] && d_handler[i]->writable())
+ FD_SET(i, &wr_set);
+ }
+
+ tmp = master;
+ int retval = select(d_max_index+1, &rd_set, &wr_set, 0, &tmp);
+ if (retval == 0) // timed out with nothing ready
+ continue;
+ if (retval < 0){
+ if (errno == EINTR)
+ continue;
+ perror ("gr_dispatcher/select");
+ return;
+ }
+
+ for (int i = 0; i <= d_max_index; i++){
+ if (FD_ISSET(i, &rd_set))
+ if (d_handler[i])
+ d_handler[i]->handle_read();
+ if (FD_ISSET(i, &wr_set))
+ if (d_handler[i])
+ d_handler[i]->handle_write();
+ }
+ }
+}
+
+#endif
diff --git a/gnuradio-core/src/lib/runtime/gr_dispatcher.h b/gnuradio-core/src/lib/runtime/gr_dispatcher.h
new file mode 100644
index 0000000000..a3d8579727
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_dispatcher.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_DISPATCHER_H
+#define INCLUDED_GR_DISPATCHER_H
+
+#include <gr_select_handler.h>
+#include <vector>
+
+class gr_dispatcher;
+typedef boost::shared_ptr<gr_dispatcher> gr_dispatcher_sptr;
+
+gr_dispatcher_sptr gr_dispatcher_singleton();
+gr_dispatcher_sptr gr_make_dispatcher();
+
+/*!
+ * \brief invoke callbacks based on select.
+ *
+ * \sa gr_select_handler
+ */
+class gr_dispatcher
+{
+ gr_dispatcher();
+ friend gr_dispatcher_sptr gr_make_dispatcher();
+
+ std::vector<gr_select_handler_sptr> d_handler;
+ int d_max_index;
+
+public:
+ ~gr_dispatcher();
+
+ bool add_handler(gr_select_handler_sptr handler);
+ bool del_handler(gr_select_handler_sptr handler);
+ bool del_handler(gr_select_handler *handler);
+
+ /*!
+ * \brief Event dispatching loop.
+ *
+ * Enter a polling loop that only terminates after all gr_select_handlers
+ * have been removed. \p timeout sets the timeout parameter to the select()
+ * call, measured in seconds.
+ *
+ * \param timeout maximum number of seconds to block in select.
+ */
+ void loop(double timeout=10);
+};
+
+#endif /* INCLUDED_GR_DISPATCHER_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_dispatcher.i b/gnuradio-core/src/lib/runtime/gr_dispatcher.i
new file mode 100644
index 0000000000..5feca75713
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+class gr_dispatcher;
+typedef boost::shared_ptr<gr_dispatcher> gr_dispatcher_sptr;
+%template(gr_dispatcher_sptr) boost::shared_ptr<gr_dispatcher>;
+
+%rename(dispatcher) gr_make_dispatcher;
+gr_dispatcher_sptr gr_make_dispatcher();
+
+%rename(dispatcher_singleton) gr_dispatcher_singleton;
+gr_dispatcher_sptr gr_dispatcher_singleton();
+
+/*!
+ * \brief invoke callbacks based on select.
+ *
+ * \sa gr_select_handler
+ */
+class gr_dispatcher
+{
+ gr_dispatcher();
+
+public:
+ ~gr_dispatcher();
+
+ /*!
+ * \brief Event dispatching loop.
+ *
+ * Enter a polling loop that only terminates after all gr_select_handlers
+ * have been removed. \p timeout sets the timeout parameter to the select()
+ * call, measured in seconds.
+ *
+ * \param timeout maximum number of seconds to block in select.
+ */
+ void loop(double timeout=10);
+};
diff --git a/gnuradio-core/src/lib/runtime/gr_error_handler.cc b/gnuradio-core/src/lib/runtime/gr_error_handler.cc
new file mode 100644
index 0000000000..a3148cfde6
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+ * This code is based on error.cc from the "Click Modular Router".
+ * Original copyright follows:
+ */
+/*
+ * error.{cc,hh} -- flexible classes for error reporting
+ * Eddie Kohler
+ *
+ * Copyright (c) 1999-2000 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, subject to the conditions
+ * listed in the Click LICENSE file. These conditions include: you must
+ * preserve this copyright notice, and you cannot mention the copyright
+ * holders in advertising related to the Software without their permission.
+ * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
+ * notice is a summary of the Click LICENSE file; the license in that file is
+ * legally binding.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_error_handler.h>
+#include <assert.h>
+#include <stdexcept>
+#include <unistd.h>
+
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+static gr_error_handler *s_default_handler = 0;
+static gr_error_handler *s_silent_handler = 0;
+
+bool
+gr_error_handler::has_default_handler()
+{
+ return s_default_handler != 0;
+}
+
+void
+gr_error_handler::set_default_handler(gr_error_handler *errh)
+{
+ s_default_handler = errh;
+}
+
+gr_error_handler *
+gr_error_handler::default_handler()
+{
+ assert (s_default_handler != 0);
+ return s_default_handler;
+}
+
+gr_error_handler *
+gr_error_handler::silent_handler()
+{
+ assert (s_silent_handler != 0);
+ return s_silent_handler;
+}
+
+// ----------------------------------------------------------------
+
+gr_error_handler::~gr_error_handler()
+{
+ // nop
+}
+
+void
+gr_error_handler::debug(const char *format, ...)
+{
+ va_list val;
+ va_start(val, format);
+ verror(ERR_DEBUG, format, val);
+ va_end(val);
+}
+
+void
+gr_error_handler::message(const char *format, ...)
+{
+ va_list val;
+ va_start(val, format);
+ verror(ERR_MESSAGE, format, val);
+ va_end(val);
+}
+
+void
+gr_error_handler::warning(const char *format, ...)
+{
+ va_list val;
+ va_start(val, format);
+ verror(ERR_WARNING, format, val);
+ va_end(val);
+}
+
+void
+gr_error_handler::error(const char *format, ...)
+{
+ va_list val;
+ va_start(val, format);
+ verror(ERR_ERROR, format, val);
+ va_end(val);
+}
+
+void
+gr_error_handler::fatal(const char *format, ...)
+{
+ va_list val;
+ va_start(val, format);
+ verror(ERR_FATAL, format, val);
+ va_end(val);
+}
+
+void
+gr_error_handler::verror(seriousness s, const char *format, va_list val)
+{
+ std::string text = make_text(s, format, val);
+ handle_text(s, text);
+ count_error(s);
+}
+
+void
+gr_error_handler::verror_text(seriousness s, const std::string &text)
+{
+ // text is already made
+ handle_text(s, text);
+ count_error(s);
+}
+
+std::string
+gr_error_handler::make_text(seriousness s, const char *format, va_list val)
+{
+ char text_buf[4096];
+ vsnprintf(text_buf, sizeof(text_buf), format, val);
+ text_buf[sizeof(text_buf)-1] = 0;
+ return text_buf;
+}
+
+// ----------------------------------------------------------------
+
+void
+gr_base_error_handler::count_error(seriousness s)
+{
+ if (s < ERR_WARNING)
+ /* do nothing */;
+ else if (s < ERR_ERROR)
+ d_nwarnings++;
+ else
+ d_nerrors++;
+}
+
+// ----------------------------------------------------------------
+
+gr_file_error_handler::gr_file_error_handler(FILE *file)
+ : d_file(file), d_fd(-1)
+{
+}
+
+gr_file_error_handler::gr_file_error_handler(int file_descriptor)
+{
+ d_fd = dup(file_descriptor); // so we can fclose it
+ if (d_fd == -1){
+ perror("gr_file_error_handler:dup");
+ throw std::invalid_argument("gr_file_error_handler:dup");
+ }
+ d_file = fdopen(d_fd, "w");
+ if (d_file == 0){
+ perror("gr_file_error_handler:fdopen");
+ throw std::invalid_argument("gr_file_error_handler:fdopen");
+ }
+}
+
+gr_file_error_handler::~gr_file_error_handler()
+{
+ if (d_fd != -1){
+ fclose(d_file);
+ }
+}
+
+void
+gr_file_error_handler::handle_text(seriousness s, const std::string &text)
+{
+ if (text.length() <= 0)
+ return;
+
+ fwrite(text.data(), 1, text.length(), d_file);
+ if (text[text.length()-1] != '\n')
+ fwrite("\n", 1, 1, d_file);
+
+ if (d_fd != -1)
+ fflush(d_file); // keep synced with any other users of fd
+}
+
+
+// ----------------------------------------------------------------
+// static error handlers
+//
+
+class gr_silent_error_handler : public gr_base_error_handler
+{
+public:
+ gr_silent_error_handler() {}
+ void handle_text(seriousness s, const std::string &str);
+};
+
+void
+gr_silent_error_handler::handle_text(seriousness s, const std::string &str)
+{
+ // nop
+}
+
+class force_init {
+public:
+ force_init()
+ {
+ s_default_handler = new gr_file_error_handler(stdout);
+ s_silent_handler = new gr_silent_error_handler();
+ }
+};
+
+static force_init kludge;
diff --git a/gnuradio-core/src/lib/runtime/gr_error_handler.h b/gnuradio-core/src/lib/runtime/gr_error_handler.h
new file mode 100644
index 0000000000..275db64c33
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_error_handler.h
@@ -0,0 +1,114 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+ * This code is based on error.hh from the "Click Modular Router".
+ * Original copyright follows:
+ */
+/*
+ * error.{cc,hh} -- flexible classes for error reporting
+ * Eddie Kohler
+ *
+ * Copyright (c) 1999-2000 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, subject to the conditions
+ * listed in the Click LICENSE file. These conditions include: you must
+ * preserve this copyright notice, and you cannot mention the copyright
+ * holders in advertising related to the Software without their permission.
+ * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
+ * notice is a summary of the Click LICENSE file; the license in that file is
+ * legally binding.
+ */
+
+#ifndef INCLUDED_GR_ERROR_HANDLER_H
+#define INCLUDED_GR_ERROR_HANDLER_H
+
+#include <stdarg.h>
+#include <string>
+
+/*!
+ * \brief abstract error handler
+ */
+class gr_error_handler {
+public:
+ enum seriousness {
+ ERR_DEBUG = 0x00000000,
+ ERR_MESSAGE = 0x00010000,
+ ERR_WARNING = 0x00020000,
+ ERR_ERROR = 0x00030000,
+ ERR_FATAL = 0x00040000
+ };
+
+ gr_error_handler() {}
+ virtual ~gr_error_handler();
+
+ static gr_error_handler *default_handler();
+ static gr_error_handler *silent_handler();
+
+ static bool has_default_handler();
+ static void set_default_handler(gr_error_handler *errh);
+
+ void debug(const char *format, ...);
+ void message(const char *format, ...);
+ void warning(const char *format, ...);
+ void error(const char *format, ...);
+ void fatal(const char *format, ...);
+
+ virtual int nwarnings() const = 0;
+ virtual int nerrors() const = 0;
+ virtual void reset_counts() = 0;
+
+ void verror(seriousness s, const char *format, va_list);
+ void verror_text(seriousness s, const std::string &text);
+
+protected:
+ virtual void count_error(seriousness s) = 0;
+ virtual void handle_text(seriousness s, const std::string &str) = 0;
+ std::string make_text(seriousness s, const char *format, va_list);
+};
+
+
+class gr_base_error_handler : public gr_error_handler {
+ int d_nwarnings;
+ int d_nerrors;
+
+public:
+ gr_base_error_handler() : d_nwarnings(0), d_nerrors(0) {}
+ int nwarnings() const { return d_nwarnings; }
+ int nerrors() const { return d_nerrors; }
+ void reset_counts() { d_nwarnings = d_nerrors = 0; }
+ void count_error(seriousness s);
+};
+
+class gr_file_error_handler : public gr_base_error_handler {
+ FILE *d_file;
+ int d_fd;
+public:
+ gr_file_error_handler(FILE *file);
+ gr_file_error_handler(int file_descriptor);
+ ~gr_file_error_handler();
+
+ void handle_text(seriousness s, const std::string &str);
+};
+
+#endif /* INCLUDED_GR_ERROR_HANDLER_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_error_handler.i b/gnuradio-core/src/lib/runtime/gr_error_handler.i
new file mode 100644
index 0000000000..d0e61496f4
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+%rename(error_handler) gr_error_handler;
+%rename(file_error_handler) gr_file_error_handler;
+
+class gr_error_handler {
+public:
+ enum seriousness {
+ ERR_DEBUG = 0x00000000,
+ ERR_MESSAGE = 0x00010000,
+ ERR_WARNING = 0x00020000,
+ ERR_ERROR = 0x00030000,
+ ERR_FATAL = 0x00040000
+ };
+
+ gr_error_handler() {}
+ virtual ~gr_error_handler();
+
+ static gr_error_handler *default_handler();
+ static gr_error_handler *silent_handler();
+
+ static bool has_default_handler();
+ static void set_default_handler(gr_error_handler *errh);
+
+ virtual int nwarnings() const = 0;
+ virtual int nerrors() const = 0;
+ virtual void reset_counts() = 0;
+
+ void verror_text(seriousness s, const std::string &text);
+};
+
+%ignore gr_base_error_handler;
+class gr_base_error_handler : public gr_error_handler {
+ int d_nwarnings;
+ int d_nerrors;
+
+public:
+ gr_base_error_handler() : d_nwarnings(0), d_nerrors(0) {}
+ int nwarnings() const { return d_nwarnings; }
+ int nerrors() const { return d_nerrors; }
+ void reset_counts() { d_nwarnings = d_nerrors = 0; }
+ void count_error(seriousness s);
+};
+
+class gr_file_error_handler : public gr_base_error_handler {
+public:
+ gr_file_error_handler(int file_descriptor);
+ ~gr_file_error_handler();
+};
diff --git a/gnuradio-core/src/lib/runtime/gr_io_signature.cc b/gnuradio-core/src/lib/runtime/gr_io_signature.cc
new file mode 100644
index 0000000000..7277108cae
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_io_signature.cc
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <iostream>
+
+gr_io_signature::gr_io_signature (int min_streams, int max_streams, size_t sizeof_stream_item)
+{
+ if (min_streams < 0
+ || (max_streams != IO_INFINITE && max_streams < min_streams))
+ throw std::invalid_argument ("gr_io_signature");
+
+ d_min_streams = min_streams;
+ d_max_streams = max_streams;
+ d_sizeof_stream_item = sizeof_stream_item;
+}
+
+gr_io_signature::~gr_io_signature ()
+{
+ // NOP for now
+ // std::cout << "destroying gr_io_signature: " << this << '\n';
+}
+
+gr_io_signature_sptr
+gr_make_io_signature (int min_streams, int max_streams, size_t sizeof_stream_item)
+{
+ return gr_io_signature_sptr (new gr_io_signature (min_streams, max_streams,
+ sizeof_stream_item));
+}
+
+
diff --git a/gnuradio-core/src/lib/runtime/gr_io_signature.h b/gnuradio-core/src/lib/runtime/gr_io_signature.h
new file mode 100644
index 0000000000..e0d979070c
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_io_signature.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_IO_SIGNATURE_H
+#define INCLUDED_IO_SIGNATURE_H
+
+#include <gr_runtime.h>
+
+/*!
+ * \brief i/o signature for input and output ports.
+ *
+ * For now, we restrict all streams to be the same type.
+ * We can fix this later.
+ */
+
+class gr_io_signature {
+ public:
+
+ static const int IO_INFINITE = -1;
+
+ ~gr_io_signature ();
+
+ int min_streams () const { return d_min_streams; }
+ int max_streams () const { return d_max_streams; }
+ size_t sizeof_stream_item (int index) const { return d_sizeof_stream_item; }
+
+ // ----------------------------------------------------------------------------
+
+ private:
+
+ int d_min_streams;
+ int d_max_streams;
+ size_t d_sizeof_stream_item;
+
+ gr_io_signature (int min_streams, int max_streams, size_t sizeof_stream_item);
+
+ friend gr_io_signature_sptr gr_make_io_signature (int min_streams,
+ int max_streams,
+ size_t sizeof_stream_item);
+};
+
+gr_io_signature_sptr
+gr_make_io_signature (int min_streams, int max_streams, size_t sizeof_stream_item);
+
+
+#endif /* INCLUDED_IO_SIGNATURE_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_io_signature.i b/gnuradio-core/src/lib/runtime/gr_io_signature.i
new file mode 100644
index 0000000000..601142e287
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_io_signature.i
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+class gr_io_signature;
+typedef boost::shared_ptr<gr_io_signature> gr_io_signature_sptr;
+%template(gr_io_signature_sptr) boost::shared_ptr<gr_io_signature>;
+
+%rename(io_signature) gr_make_io_signature;
+
+gr_io_signature_sptr
+gr_make_io_signature (int min_streams,
+ int max_streams,
+ size_t sizeof_stream_item);
+
+class gr_io_signature {
+ public:
+
+ // disabled. Suspected bug in SWIG 1.3.24
+ // static const int IO_INFINITE = -1;
+
+ ~gr_io_signature ();
+
+ int min_streams () const { return d_min_streams; }
+ int max_streams () const { return d_max_streams; }
+ size_t sizeof_stream_item (int index) const { return d_sizeof_stream_item; }
+
+ private:
+ gr_io_signature (int min_streams, int max_streams, size_t sizeof_stream_item);
+};
+
diff --git a/gnuradio-core/src/lib/runtime/gr_local_sighandler.cc b/gnuradio-core/src/lib/runtime/gr_local_sighandler.cc
new file mode 100644
index 0000000000..c6da0978c3
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_local_sighandler.cc
@@ -0,0 +1,186 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_local_sighandler.h>
+#include <stdexcept>
+#include <stdio.h>
+
+
+gr_local_sighandler::gr_local_sighandler (int signum,
+ void (*new_handler)(int))
+ : d_signum (signum)
+{
+#ifdef HAVE_SIGACTION
+ struct sigaction new_action;
+ memset (&new_action, 0, sizeof (new_action));
+
+ new_action.sa_handler = new_handler;
+ sigemptyset (&new_action.sa_mask);
+ new_action.sa_flags = 0;
+
+ if (sigaction (d_signum, &new_action, &d_old_action) < 0){
+ perror ("sigaction (install new)");
+ throw std::runtime_error ("sigaction");
+ }
+#endif
+}
+
+gr_local_sighandler::~gr_local_sighandler ()
+{
+#ifdef HAVE_SIGACTION
+ if (sigaction (d_signum, &d_old_action, 0) < 0){
+ perror ("sigaction (restore old)");
+ throw std::runtime_error ("sigaction");
+ }
+#endif
+}
+
+void
+gr_local_sighandler::throw_signal (int signum)
+{
+ throw gr_signal (signum);
+}
+
+/*
+ * Semi-hideous way to may a signal number into a signal name
+ */
+
+#define SIGNAME(x) case x: return #x
+
+std::string
+gr_signal::name () const
+{
+ char tmp[128];
+
+ switch (signal ()){
+#ifdef SIGHUP
+ SIGNAME (SIGHUP);
+#endif
+#ifdef SIGINT
+ SIGNAME (SIGINT);
+#endif
+#ifdef SIGQUIT
+ SIGNAME (SIGQUIT);
+#endif
+#ifdef SIGILL
+ SIGNAME (SIGILL);
+#endif
+#ifdef SIGTRAP
+ SIGNAME (SIGTRAP);
+#endif
+#ifdef SIGABRT
+ SIGNAME (SIGABRT);
+#endif
+#ifdef SIGBUS
+ SIGNAME (SIGBUS);
+#endif
+#ifdef SIGFPE
+ SIGNAME (SIGFPE);
+#endif
+#ifdef SIGKILL
+ SIGNAME (SIGKILL);
+#endif
+#ifdef SIGUSR1
+ SIGNAME (SIGUSR1);
+#endif
+#ifdef SIGSEGV
+ SIGNAME (SIGSEGV);
+#endif
+#ifdef SIGUSR2
+ SIGNAME (SIGUSR2);
+#endif
+#ifdef SIGPIPE
+ SIGNAME (SIGPIPE);
+#endif
+#ifdef SIGALRM
+ SIGNAME (SIGALRM);
+#endif
+#ifdef SIGTERM
+ SIGNAME (SIGTERM);
+#endif
+#ifdef SIGSTKFLT
+ SIGNAME (SIGSTKFLT);
+#endif
+#ifdef SIGCHLD
+ SIGNAME (SIGCHLD);
+#endif
+#ifdef SIGCONT
+ SIGNAME (SIGCONT);
+#endif
+#ifdef SIGSTOP
+ SIGNAME (SIGSTOP);
+#endif
+#ifdef SIGTSTP
+ SIGNAME (SIGTSTP);
+#endif
+#ifdef SIGTTIN
+ SIGNAME (SIGTTIN);
+#endif
+#ifdef SIGTTOU
+ SIGNAME (SIGTTOU);
+#endif
+#ifdef SIGURG
+ SIGNAME (SIGURG);
+#endif
+#ifdef SIGXCPU
+ SIGNAME (SIGXCPU);
+#endif
+#ifdef SIGXFSZ
+ SIGNAME (SIGXFSZ);
+#endif
+#ifdef SIGVTALRM
+ SIGNAME (SIGVTALRM);
+#endif
+#ifdef SIGPROF
+ SIGNAME (SIGPROF);
+#endif
+#ifdef SIGWINCH
+ SIGNAME (SIGWINCH);
+#endif
+#ifdef SIGIO
+ SIGNAME (SIGIO);
+#endif
+#ifdef SIGPWR
+ SIGNAME (SIGPWR);
+#endif
+#ifdef SIGSYS
+ SIGNAME (SIGSYS);
+#endif
+ default:
+#if defined (HAVE_SNPRINTF)
+#if defined (SIGRTMIN) && defined (SIGRTMAX)
+ if (signal () >= SIGRTMIN && signal () <= SIGRTMAX){
+ snprintf (tmp, sizeof (tmp), "SIGRTMIN + %d", signal ());
+ return tmp;
+ }
+#endif
+ snprintf (tmp, sizeof (tmp), "SIGNAL %d", signal ());
+ return tmp;
+#else
+ return "Unknown signal";
+#endif
+ }
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_local_sighandler.h b/gnuradio-core/src/lib/runtime/gr_local_sighandler.h
new file mode 100644
index 0000000000..69eb65d80d
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_local_sighandler.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_LOCAL_SIGHANDLER_H
+#define INCLUDED_GR_LOCAL_SIGHANDLER_H
+
+#include <signal.h>
+#include <string>
+
+/*!
+ * \brief Get and set signal handler.
+ *
+ * Constructor installs new handler, destructor reinstalls
+ * original value.
+ */
+class gr_local_sighandler {
+ int d_signum;
+#ifdef HAVE_SIGACTION
+ struct sigaction d_old_action;
+#endif
+public:
+ gr_local_sighandler (int signum, void (*new_handler)(int));
+ ~gr_local_sighandler ();
+
+ /* throw gr_signal (signum) */
+ static void throw_signal (int signum);
+};
+
+/*!
+ * \brief Representation of signal.
+ */
+class gr_signal
+{
+ int d_signum;
+public:
+ gr_signal (int signum) : d_signum (signum) {}
+ int signal () const { return d_signum; }
+ std::string name () const;
+};
+
+#endif /* INCLUDED_GR_LOCAL_SIGHANDLER_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_message.cc b/gnuradio-core/src/lib/runtime/gr_message.cc
new file mode 100644
index 0000000000..e9427e64df
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_message.cc
@@ -0,0 +1,77 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_message.h>
+#include <assert.h>
+
+static long s_ncurrently_allocated = 0;
+
+gr_message_sptr
+gr_make_message (long type, double arg1, double arg2, size_t length)
+{
+ return gr_message_sptr (new gr_message (type, arg1, arg2, length));
+}
+
+gr_message_sptr
+gr_make_message_from_string(const std::string s, long type, double arg1, double arg2)
+{
+ gr_message_sptr m = gr_make_message(type, arg1, arg2, s.size());
+ memcpy(m->msg(), s.data(), s.size());
+ return m;
+}
+
+
+gr_message::gr_message (long type, double arg1, double arg2, size_t length)
+ : d_type(type), d_arg1(arg1), d_arg2(arg2)
+{
+ if (length == 0)
+ d_buf_start = d_msg_start = d_msg_end = d_buf_end = 0;
+ else {
+ d_buf_start = new unsigned char [length];
+ d_msg_start = d_buf_start;
+ d_msg_end = d_buf_end = d_buf_start + length;
+ }
+ s_ncurrently_allocated++;
+}
+
+gr_message::~gr_message ()
+{
+ assert (d_next == 0);
+ delete [] d_buf_start;
+ d_msg_start = d_msg_end = d_buf_end = 0;
+ s_ncurrently_allocated--;
+}
+
+std::string
+gr_message::to_string() const
+{
+ return std::string((char *)d_msg_start, length());
+}
+
+long
+gr_message_ncurrently_allocated ()
+{
+ return s_ncurrently_allocated;
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_message.h b/gnuradio-core/src/lib/runtime/gr_message.h
new file mode 100644
index 0000000000..272a82ee47
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_message.h
@@ -0,0 +1,89 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_MESSAGE_H
+#define INCLUDED_GR_MESSAGE_H
+
+#include <gr_types.h>
+#include <string>
+
+class gr_message;
+typedef boost::shared_ptr<gr_message> gr_message_sptr;
+
+/*!
+ * \brief public constructor for gr_message
+ */
+gr_message_sptr
+gr_make_message(long type = 0, double arg1 = 0, double arg2 = 0, size_t length = 0);
+
+gr_message_sptr
+gr_make_message_from_string(const std::string s, long type = 0, double arg1 = 0, double arg2 = 0);
+
+/*!
+ * \brief Message.
+ *
+ * The ideas and method names for adjustable message length were
+ * lifted from the click modular router "Packet" class.
+ */
+class gr_message {
+ gr_message_sptr d_next; // link field for msg queue
+ long d_type; // type of the message
+ double d_arg1; // optional arg1
+ double d_arg2; // optional arg2
+
+ unsigned char *d_buf_start; // start of allocated buffer
+ unsigned char *d_msg_start; // where the msg starts
+ unsigned char *d_msg_end; // one beyond end of msg
+ unsigned char *d_buf_end; // one beyond end of allocated buffer
+
+ gr_message (long type, double arg1, double arg2, size_t length);
+
+ friend gr_message_sptr
+ gr_make_message (long type, double arg1, double arg2, size_t length);
+
+ friend gr_message_sptr
+ gr_make_message_from_string (const std::string s, long type, double arg1, double arg2);
+
+ friend class gr_msg_queue;
+
+ unsigned char *buf_data() const { return d_buf_start; }
+ size_t buf_len() const { return d_buf_end - d_buf_start; }
+
+public:
+ ~gr_message ();
+
+ long type() const { return d_type; }
+ double arg1() const { return d_arg1; }
+ double arg2() const { return d_arg2; }
+
+ void set_type(long type) { d_type = type; }
+ void set_arg1(double arg1) { d_arg1 = arg1; }
+ void set_arg2(double arg2) { d_arg2 = arg2; }
+
+ unsigned char *msg() const { return d_msg_start; }
+ size_t length() const { return d_msg_end - d_msg_start; }
+ std::string to_string() const;
+
+};
+
+long gr_message_ncurrently_allocated ();
+
+#endif /* INCLUDED_GR_MESSAGE_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_message.i b/gnuradio-core/src/lib/runtime/gr_message.i
new file mode 100644
index 0000000000..19d5d1cd17
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+class gr_message;
+typedef boost::shared_ptr<gr_message> gr_message_sptr;
+%template(gr_message_sptr) boost::shared_ptr<gr_message>;
+
+%rename(message_from_string) gr_make_message_from_string;
+gr_message_sptr
+gr_make_message_from_string(const std::string s, long type = 0, double arg1 = 0, double arg2 = 0);
+
+%rename(message) gr_make_message;
+gr_message_sptr
+gr_make_message(long type = 0, double arg1 = 0, double arg2 = 0, size_t length = 0);
+
+/*!
+ * \brief Message.
+ *
+ * The ideas and method names for adjustable message length were
+ * lifted from the click modular router "Packet" class.
+ */
+class gr_message {
+ gr_message (long type, double arg1, double arg2, size_t length);
+
+ unsigned char *buf_data() const { return d_buf_start; }
+ size_t buf_len() const { return d_buf_end - d_buf_start; }
+
+public:
+ ~gr_message ();
+
+ long type() const { return d_type; }
+ double arg1() const { return d_arg1; }
+ double arg2() const { return d_arg2; }
+
+ void set_type(long type) { d_type = type; }
+ void set_arg1(double arg1) { d_arg1 = arg1; }
+ void set_arg2(double arg2) { d_arg2 = arg2; }
+
+ size_t length() const;
+ std::string to_string() const;
+
+};
+
+%rename(message_ncurrently_allocated) gr_message_ncurrently_allocated;
+long gr_message_ncurrently_allocated();
+
diff --git a/gnuradio-core/src/lib/runtime/gr_msg_handler.cc b/gnuradio-core/src/lib/runtime/gr_msg_handler.cc
new file mode 100644
index 0000000000..98007e239a
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_msg_handler.h>
+
+gr_msg_handler::~gr_msg_handler ()
+{
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_msg_handler.h b/gnuradio-core/src/lib/runtime/gr_msg_handler.h
new file mode 100644
index 0000000000..15aab338a5
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_msg_handler.h
@@ -0,0 +1,41 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_MSG_HANDLER_H
+#define INCLUDED_GR_MSG_HANDLER_H
+
+#include <gr_message.h>
+
+class gr_msg_handler;
+typedef boost::shared_ptr<gr_msg_handler> gr_msg_handler_sptr;
+
+/*!
+ * \brief abstract class of message handlers
+ */
+class gr_msg_handler {
+public:
+ virtual ~gr_msg_handler ();
+
+ //! handle \p msg
+ virtual void handle (gr_message_sptr msg) = 0;
+};
+
+#endif /* INCLUDED_GR_MSG_HANDLER_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_msg_handler.i b/gnuradio-core/src/lib/runtime/gr_msg_handler.i
new file mode 100644
index 0000000000..5571665ac7
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*!
+ * \brief abstract class of message handlers
+ */
+class gr_msg_handler {
+public:
+ virtual ~gr_msg_handler () = 0;
+
+ //! handle \p msg
+ virtual void handle (gr_message_sptr msg) = 0;
+};
diff --git a/gnuradio-core/src/lib/runtime/gr_msg_queue.cc b/gnuradio-core/src/lib/runtime/gr_msg_queue.cc
new file mode 100644
index 0000000000..6b53fc7ea1
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_msg_queue.cc
@@ -0,0 +1,127 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_msg_queue.h>
+#include <stdexcept>
+
+
+gr_msg_queue_sptr
+gr_make_msg_queue(unsigned int limit)
+{
+ return gr_msg_queue_sptr (new gr_msg_queue(limit));
+}
+
+
+gr_msg_queue::gr_msg_queue(unsigned int limit)
+ : d_not_empty(&d_mutex), d_not_full(&d_mutex),
+ /*d_head(0), d_tail(0),*/ d_count(0), d_limit(limit)
+{
+}
+
+gr_msg_queue::~gr_msg_queue()
+{
+ flush ();
+}
+
+void
+gr_msg_queue::insert_tail(gr_message_sptr msg)
+{
+ if (msg->d_next)
+ throw std::invalid_argument("gr_msg_queue::insert_tail: msg already in queue");
+
+ omni_mutex_lock l(d_mutex);
+
+ while (full_p())
+ d_not_full.wait();
+
+ if (d_tail == 0){
+ d_tail = d_head = msg;
+ //msg->d_next = 0;
+ msg->d_next.reset();
+ }
+ else {
+ d_tail->d_next = msg;
+ d_tail = msg;
+ //msg->d_next = 0;
+ msg->d_next.reset();
+ }
+ d_count++;
+ d_not_empty.signal();
+}
+
+gr_message_sptr
+gr_msg_queue::delete_head()
+{
+ omni_mutex_lock l(d_mutex);
+ gr_message_sptr m;
+
+ while ((m = d_head) == 0)
+ d_not_empty.wait();
+
+ d_head = m->d_next;
+ if (d_head == 0){
+ //d_tail = 0;
+ d_tail.reset();
+ }
+
+ d_count--;
+ // m->d_next = 0;
+ m->d_next.reset();
+ d_not_full.signal();
+ return m;
+}
+
+gr_message_sptr
+gr_msg_queue::delete_head_nowait()
+{
+ omni_mutex_lock l(d_mutex);
+ gr_message_sptr m;
+
+ if ((m = d_head) == 0){
+ //return 0;
+ return gr_message_sptr();
+ }
+
+ d_head = m->d_next;
+ if (d_head == 0){
+ //d_tail = 0;
+ d_tail.reset();
+ }
+
+ d_count--;
+ //m->d_next = 0;
+ m->d_next.reset();
+ d_not_full.signal();
+ return m;
+}
+
+void
+gr_msg_queue::flush()
+{
+ gr_message_sptr m;
+
+ while ((m = delete_head_nowait ()) != 0)
+ ;
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_msg_queue.h b/gnuradio-core/src/lib/runtime/gr_msg_queue.h
new file mode 100644
index 0000000000..6a9147ee38
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_msg_queue.h
@@ -0,0 +1,89 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_MSG_QUEUE_H
+#define INCLUDED_GR_MSG_QUEUE_H
+
+#include <gr_msg_handler.h>
+#include <omnithread.h>
+
+class gr_msg_queue;
+typedef boost::shared_ptr<gr_msg_queue> gr_msg_queue_sptr;
+
+gr_msg_queue_sptr gr_make_msg_queue(unsigned int limit=0);
+
+/*!
+ * \brief thread-safe message queue
+ */
+class gr_msg_queue : public gr_msg_handler {
+ omni_mutex d_mutex;
+ omni_condition d_not_empty;
+ omni_condition d_not_full;
+ gr_message_sptr d_head;
+ gr_message_sptr d_tail;
+ unsigned int d_count; // # of messages in queue.
+ unsigned int d_limit; // max # of messages in queue. 0 -> unbounded
+
+public:
+ gr_msg_queue(unsigned int limit);
+ ~gr_msg_queue();
+
+ //! Generic msg_handler method: insert the message.
+ void handle(gr_message_sptr msg) { insert_tail (msg); }
+
+ /*!
+ * \brief Insert message at tail of queue.
+ * \param msg message
+ *
+ * Block if queue if full.
+ */
+ void insert_tail(gr_message_sptr msg);
+
+ /*!
+ * \brief Delete message from head of queue and return it.
+ * Block if no message is available.
+ */
+ gr_message_sptr delete_head();
+
+ /*!
+ * \brief If there's a message in the q, delete it and return it.
+ * If no message is available, return 0.
+ */
+ gr_message_sptr delete_head_nowait();
+
+ //! Delete all messages from the queue
+ void flush();
+
+ //! is the queue empty?
+ bool empty_p() const { return d_count == 0; }
+
+ //! is the queue full?
+ bool full_p() const { return d_limit != 0 && d_count >= d_limit; }
+
+ //! return number of messages in queue
+ unsigned int count() const { return d_count; }
+
+ //! return limit on number of message in queue. 0 -> unbounded
+ unsigned int limit() const { return d_limit; }
+
+};
+
+#endif /* INCLUDED_GR_MSG_QUEUE_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_msg_queue.i b/gnuradio-core/src/lib/runtime/gr_msg_queue.i
new file mode 100644
index 0000000000..28292d66fb
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_msg_queue.i
@@ -0,0 +1,111 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+class gr_msg_queue;
+typedef boost::shared_ptr<gr_msg_queue> gr_msg_queue_sptr;
+%template(gr_msg_queue_sptr) boost::shared_ptr<gr_msg_queue>;
+
+%rename(msg_queue) gr_make_msg_queue;
+gr_msg_queue_sptr gr_make_msg_queue(unsigned limit=0);
+
+/*!
+ * \brief thread-safe message queue
+ */
+%ignore gr_msg_queue;
+class gr_msg_queue : public gr_msg_handler {
+ omni_mutex d_mutex;
+ omni_condition d_cond;
+ gr_message_sptr d_head;
+ gr_message_sptr d_tail;
+ int d_count;
+
+public:
+ gr_msg_queue();
+ ~gr_msg_queue();
+
+ //! Generic msg_handler method: insert the message.
+ //void handle(gr_message_sptr msg) { insert_tail (msg); }
+
+ /*!
+ * \brief Insert message at tail of queue.
+ * \param msg message
+ *
+ * Block if queue if full.
+ */
+ //void insert_tail(gr_message_sptr msg);
+
+ /*!
+ * \brief Delete message from head of queue and return it.
+ * Block if no message is available.
+ */
+ //gr_message_sptr delete_head();
+
+ /*!
+ * \brief If there's a message in the q, delete it and return it.
+ * If no message is available, return 0.
+ */
+ gr_message_sptr delete_head_nowait();
+
+ //! is the queue empty?
+ bool empty_p() const;
+
+ //! is the queue full?
+ bool full_p() const;
+
+ //! return number of messages in queue
+ unsigned int count() const;
+
+ //! Delete all messages from the queue
+ void flush();
+};
+
+/*
+ * The following kludge-o-rama releases the Python global interpreter
+ * lock around these potentially blocking calls. We don't want
+ * libgnuradio-core to be dependent on Python, thus we create these
+ * functions that serve as replacements for the normal C++ delete_head
+ * and insert_tail methods. The %pythoncode smashes these new C++
+ * functions into the gr.msg_queue wrapper class, so that everything
+ * appears normal. (An evil laugh is heard in the distance...)
+ */
+%inline {
+ gr_message_sptr gr_py_msg_queue__delete_head(gr_msg_queue_sptr q) {
+ gr_message_sptr msg;
+ Py_BEGIN_ALLOW_THREADS; // release global interpreter lock
+ msg = q->delete_head(); // possibly blocking call
+ Py_END_ALLOW_THREADS; // acquire global interpreter lock
+ return msg;
+ }
+
+ void gr_py_msg_queue__insert_tail(gr_msg_queue_sptr q, gr_message_sptr msg) {
+ Py_BEGIN_ALLOW_THREADS; // release global interpreter lock
+ q->insert_tail(msg); // possibly blocking call
+ Py_END_ALLOW_THREADS; // acquire global interpreter lock
+ }
+}
+
+// smash in new python delete_head and insert_tail methods...
+%pythoncode %{
+gr_msg_queue_sptr.delete_head = gr_py_msg_queue__delete_head
+gr_msg_queue_sptr.insert_tail = gr_py_msg_queue__insert_tail
+gr_msg_queue_sptr.handle = gr_py_msg_queue__insert_tail
+%}
diff --git a/gnuradio-core/src/lib/runtime/gr_pagesize.cc b/gnuradio-core/src/lib/runtime/gr_pagesize.cc
new file mode 100644
index 0000000000..dec40678b3
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pagesize.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#if defined(_WIN32) && defined(HAVE_GETPAGESIZE)
+extern "C" size_t getpagesize(void);
+#endif
+
+int
+gr_pagesize ()
+{
+ static int s_pagesize = -1;
+
+ if (s_pagesize == -1){
+#if defined(HAVE_GETPAGESIZE)
+ s_pagesize = getpagesize ();
+#elif defined (HAVE_SYSCONF)
+ s_pagesize = sysconf (_SC_PAGESIZE);
+ if (s_pagesize == -1){
+ perror ("_SC_PAGESIZE");
+ s_pagesize = 4096;
+ }
+#else
+ fprintf (stderr, "gr_pagesize: no info; setting pagesize = 4096\n");
+ s_pagesize = 4096;
+#endif
+ }
+ return s_pagesize;
+}
+
diff --git a/gnuradio-core/src/lib/runtime/gr_pagesize.h b/gnuradio-core/src/lib/runtime/gr_pagesize.h
new file mode 100644
index 0000000000..a5cadb7074
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_pagesize.h
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _GR_PAGESIZE_H_
+#define _GR_PAGESIZE_H_
+
+/*!
+ * \brief return the page size in bytes
+ */
+
+int gr_pagesize ();
+
+
+#endif /* _GR_PAGESIZE_H_ */
diff --git a/gnuradio-core/src/lib/runtime/gr_preferences.cc b/gnuradio-core/src/lib/runtime/gr_preferences.cc
new file mode 100644
index 0000000000..854314447a
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_preferences.cc
@@ -0,0 +1,101 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_preferences.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+
+#ifdef MKDIR_TAKES_ONE_ARG
+#define gr_mkdir(pathname, mode) mkdir(pathname)
+#else
+#define gr_mkdir(pathname, mode) mkdir((pathname), (mode))
+#endif
+
+/*
+ * The simplest thing that could possibly work:
+ * the key is the filename; the value is the file contents.
+ */
+
+static const char *
+pathname (const char *key)
+{
+ static char buf[200];
+ snprintf (buf, sizeof (buf), "%s/.gnuradio/prefs/%s", getenv ("HOME"), key);
+ return buf;
+}
+
+static void
+ensure_dir_path ()
+{
+ char path[200];
+ struct stat statbuf;
+
+ snprintf (path, sizeof (path), "%s/.gnuradio/prefs", getenv ("HOME"));
+ if (stat (path, &statbuf) == 0 && S_ISDIR (statbuf.st_mode))
+ return;
+
+ // blindly try to make it // FIXME make this robust. C++ SUCKS!
+
+ snprintf (path, sizeof (path), "%s/.gnuradio", getenv ("HOME"));
+ gr_mkdir (path, 0750);
+ snprintf (path, sizeof (path), "%s/.gnuradio/prefs", getenv ("HOME"));
+ gr_mkdir (path, 0750);
+}
+
+const char *
+gr_preferences::get (const char *key)
+{
+ static char buf[1024];
+
+ FILE *fp = fopen (pathname (key), "r");
+ if (fp == 0)
+ return 0;
+
+ memset (buf, 0, sizeof (buf));
+ fread (buf, 1, sizeof (buf) - 1, fp);
+ fclose (fp);
+ return buf;
+}
+
+void
+gr_preferences::set (const char *key, const char *value)
+{
+ ensure_dir_path ();
+
+ FILE *fp = fopen (pathname (key), "w");
+ if (fp == 0){
+ perror (pathname (key));
+ return;
+ }
+
+ fwrite (value, 1, strlen (value), fp);
+ fclose (fp);
+};
diff --git a/gnuradio-core/src/lib/runtime/gr_preferences.h b/gnuradio-core/src/lib/runtime/gr_preferences.h
new file mode 100644
index 0000000000..5a7cad454d
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_preferences.h
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GR_PREFERENCES_H_
+#define _GR_PREFERENCES_H_
+
+class gr_preferences {
+ public:
+ static const char *get (const char *key);
+ static void set (const char *key, const char *value);
+};
+
+#endif /* _GR_PREFERENCES_H_ */
diff --git a/gnuradio-core/src/lib/runtime/gr_realtime.cc b/gnuradio-core/src/lib/runtime/gr_realtime.cc
new file mode 100644
index 0000000000..4f23ea0c63
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_realtime.cc
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_realtime.h>
+
+#ifdef HAVE_SCHED_H
+#include <sched.h>
+#endif
+
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+#if defined(HAVE_SCHED_SETSCHEDULER)
+
+gr_rt_status_t
+gr_enable_realtime_scheduling()
+{
+ int policy = SCHED_FIFO;
+ int pri = (sched_get_priority_max (policy) - sched_get_priority_min (policy)) / 2;
+ int pid = 0; // this process
+
+ struct sched_param param;
+ memset(&param, 0, sizeof(param));
+ param.sched_priority = pri;
+ int result = sched_setscheduler(pid, policy, &param);
+ if (result != 0){
+ if (errno == EPERM)
+ return RT_NO_PRIVS;
+ else {
+ perror ("sched_setscheduler: failed to set real time priority");
+ return RT_OTHER_ERROR;
+ }
+ }
+ //printf("SCHED_FIFO enabled with priority = %d\n", pri);
+ return RT_OK;
+}
+
+// #elif // could try negative niceness
+
+#else
+
+gr_rt_status_t
+gr_enable_realtime_scheduling()
+{
+ return RT_NOT_IMPLEMENTED;
+}
+
+#endif
diff --git a/gnuradio-core/src/lib/runtime/gr_realtime.h b/gnuradio-core/src/lib/runtime/gr_realtime.h
new file mode 100644
index 0000000000..3aeafa5338
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_realtime.h
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_REALTIME_H
+#define INCLUDED_GR_REALTIME_H
+
+typedef enum {
+ RT_OK = 0,
+ RT_NOT_IMPLEMENTED,
+ RT_NO_PRIVS,
+ RT_OTHER_ERROR
+} gr_rt_status_t;
+
+/*!
+ * \brief If possible, enable high-priority "real time" scheduling.
+ */
+gr_rt_status_t
+gr_enable_realtime_scheduling();
+
+#endif /* INCLUDED_GR_REALTIME_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_realtime.i b/gnuradio-core/src/lib/runtime/gr_realtime.i
new file mode 100644
index 0000000000..cb43e0514c
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_realtime.i
@@ -0,0 +1,4 @@
+%rename(enable_realtime_scheduling) gr_enable_realtime_scheduling;
+
+%include <gr_realtime.h>
+
diff --git a/gnuradio-core/src/lib/runtime/gr_runtime.h b/gnuradio-core/src/lib/runtime/gr_runtime.h
new file mode 100644
index 0000000000..f138e6ac41
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_runtime.h
@@ -0,0 +1,44 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_RUNTIME_H
+#define INCLUDED_GR_RUNTIME_H
+
+#include <gr_types.h>
+
+/*
+ * typedefs for smart pointers we use throughout the runtime system
+ */
+
+class gr_block;
+class gr_block_detail;
+class gr_io_signature;
+class gr_buffer;
+class gr_buffer_reader;
+
+typedef boost::shared_ptr<gr_block> gr_block_sptr;
+typedef boost::shared_ptr<gr_block_detail> gr_block_detail_sptr;
+typedef boost::shared_ptr<gr_io_signature> gr_io_signature_sptr;
+typedef boost::shared_ptr<gr_buffer> gr_buffer_sptr;
+typedef boost::shared_ptr<gr_buffer_reader> gr_buffer_reader_sptr;
+
+#endif /* INCLUDED_GR_RUNTIME_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_select_handler.cc b/gnuradio-core/src/lib/runtime/gr_select_handler.cc
new file mode 100644
index 0000000000..d85883a655
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_select_handler.h>
+
+gr_select_handler::gr_select_handler(int fd)
+ : d_fd(fd)
+{
+}
+
+gr_select_handler::~gr_select_handler()
+{
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_select_handler.h b/gnuradio-core/src/lib/runtime/gr_select_handler.h
new file mode 100644
index 0000000000..d07ff007f8
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_select_handler.h
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_SELECT_HANDLER_H
+#define INCLUDED_GR_SELECT_HANDLER_H
+
+#include <boost/shared_ptr.hpp>
+
+class gr_select_handler;
+typedef boost::shared_ptr<gr_select_handler> gr_select_handler_sptr;
+
+
+/*!
+ * \brief Abstract handler for select based notification.
+ *
+ * \sa gr_dispatcher
+ */
+class gr_select_handler
+{
+ int d_fd;
+
+protected:
+ gr_select_handler(int file_descriptor);
+
+public:
+ virtual ~gr_select_handler();
+
+ int fd() const { return d_fd; }
+ int file_descriptor() const { return d_fd; }
+
+ /*!
+ * \brief Called when file_descriptor is readable.
+ *
+ * Called when the dispatcher detects that file_descriptor can
+ * be read without blocking.
+ */
+ virtual void handle_read() = 0;
+
+ /*!
+ * \brief Called when file_descriptor is writable.
+ *
+ * Called when dispatcher detects that file descriptor can be
+ * written without blocking.
+ */
+ virtual void handle_write() = 0;
+
+ /*!
+ * Called each time around the dispatcher loop to determine whether
+ * this handler's file descriptor should be added to the list on which
+ * read events can occur. The default method returns true, indicating
+ * that by default, all handlers are interested in read events.
+ */
+ virtual bool readable() { return true; }
+
+ /*!
+ * Called each time around the dispatcher loop to determine whether
+ * this handler's file descriptor should be added to the list on which
+ * write events can occur. The default method returns true, indicating
+ * that by default, all handlers are interested in write events.
+ */
+ virtual bool writable() { return true; }
+};
+
+#endif /* INCLUDED_GR_SELECT_HANDLER_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.cc b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.cc
new file mode 100644
index 0000000000..3d401557be
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.cc
@@ -0,0 +1,360 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_single_threaded_scheduler.h>
+#include <gr_block.h>
+#include <gr_block_detail.h>
+#include <gr_buffer.h>
+#include <iostream>
+#include <limits>
+#include <assert.h>
+#include <stdio.h>
+
+// must be defined to either 0 or 1
+#define ENABLE_LOGGING 0
+
+#if (ENABLE_LOGGING)
+#define LOG(x) do { x; } while(0)
+#else
+#define LOG(x) do {;} while(0)
+#endif
+
+static int which_scheduler = 0;
+
+
+std::ostream&
+operator << (std::ostream& os, const gr_block *m)
+{
+ os << "<gr_block " << m->name() << " (" << m->unique_id() << ")>";
+ return os;
+}
+
+gr_single_threaded_scheduler_sptr
+gr_make_single_threaded_scheduler (const std::vector<gr_block_sptr> &blocks)
+{
+ return
+ gr_single_threaded_scheduler_sptr (new gr_single_threaded_scheduler (blocks));
+}
+
+gr_single_threaded_scheduler::gr_single_threaded_scheduler (
+ const std::vector<gr_block_sptr> &blocks)
+ : d_blocks (blocks), d_enabled (true), d_log(0)
+{
+ if (ENABLE_LOGGING){
+ char name[100];
+ snprintf(name, sizeof(name), "sst-%d.log", which_scheduler++);
+ d_log = new std::ofstream(name);
+ *d_log << "gr_single_threaded_scheduler: "
+ << d_blocks.size ()
+ << " blocks\n";
+ }
+}
+
+gr_single_threaded_scheduler::~gr_single_threaded_scheduler ()
+{
+ if (ENABLE_LOGGING)
+ delete d_log;
+}
+
+void
+gr_single_threaded_scheduler::run ()
+{
+ d_enabled = true;
+ main_loop ();
+}
+
+
+inline static unsigned int
+round_up (unsigned int n, unsigned int multiple)
+{
+ return ((n + multiple - 1) / multiple) * multiple;
+}
+
+inline static unsigned int
+round_down (unsigned int n, unsigned int multiple)
+{
+ return (n / multiple) * multiple;
+}
+
+//
+// Return minimum available write space in all our downstream buffers
+// or -1 if we're output blocked and the output we're blocked
+// on is done.
+//
+static int
+min_available_space (gr_block_detail *d, int output_multiple)
+{
+ int min_space = std::numeric_limits<int>::max();
+
+ for (int i = 0; i < d->noutputs (); i++){
+ int n = round_down (d->output(i)->space_available (), output_multiple);
+ if (n == 0){ // We're blocked on output.
+ if (d->output(i)->done()){ // Downstream is done, therefore we're done.
+ return -1;
+ }
+ return 0;
+ }
+ min_space = std::min (min_space, n);
+ }
+ return min_space;
+}
+
+void
+gr_single_threaded_scheduler::main_loop ()
+{
+ static const int DEFAULT_CAPACITY = 16;
+
+ int noutput_items;
+ gr_vector_int ninput_items_required (DEFAULT_CAPACITY);
+ gr_vector_int ninput_items (DEFAULT_CAPACITY);
+ gr_vector_const_void_star input_items (DEFAULT_CAPACITY);
+ gr_vector_void_star output_items (DEFAULT_CAPACITY);
+ unsigned int bi;
+ unsigned int nalive;
+ int max_items_avail;
+ bool made_progress_last_pass;
+ bool making_progress;
+
+ for (unsigned i = 0; i < d_blocks.size (); i++)
+ d_blocks[i]->detail()->set_done (false); // reset any done flags
+
+ for (unsigned i = 0; i < d_blocks.size (); i++) // enable any drivers, etc.
+ d_blocks[i]->start();
+
+
+ bi = 0;
+ made_progress_last_pass = true;
+ making_progress = false;
+
+ // Loop while there are still blocks alive
+
+ nalive = d_blocks.size ();
+ while (d_enabled && nalive > 0){
+
+ gr_block *m = d_blocks[bi].get ();
+ gr_block_detail *d = m->detail().get ();
+
+ LOG(*d_log << std::endl << m);
+
+ if (d->done ())
+ goto next_block;
+
+ if (d->source_p ()){
+ // Invoke sources as a last resort. As long as the previous pass
+ // made progress, don't call a source.
+ if (made_progress_last_pass){
+ LOG(*d_log << " Skipping source\n");
+ goto next_block;
+ }
+
+ ninput_items_required.resize (0);
+ ninput_items.resize (0);
+ input_items.resize (0);
+ output_items.resize (d->noutputs ());
+
+ // determine the minimum available output space
+ noutput_items = min_available_space (d, m->output_multiple ());
+ LOG(*d_log << " source\n noutput_items = " << noutput_items << std::endl);
+ if (noutput_items == -1) // we're done
+ goto were_done;
+
+ if (noutput_items == 0){ // we're output blocked
+ LOG(*d_log << " BLKD_OUT\n");
+ goto next_block;
+ }
+
+ goto setup_call_to_work; // jump to common code
+ }
+
+ else if (d->sink_p ()){
+ ninput_items_required.resize (d->ninputs ());
+ ninput_items.resize (d->ninputs ());
+ input_items.resize (d->ninputs ());
+ output_items.resize (0);
+ LOG(*d_log << " sink\n");
+
+ max_items_avail = 0;
+ for (int i = 0; i < d->ninputs (); i++){
+ ninput_items[i] = d->input(i)->items_available();
+ //if (ninput_items[i] == 0 && d->input(i)->done())
+ if (ninput_items[i] < m->output_multiple() && d->input(i)->done())
+ goto were_done;
+
+ max_items_avail = std::max (max_items_avail, ninput_items[i]);
+ }
+
+ // take a swag at how much output we can sink
+ noutput_items = (int) (max_items_avail * m->relative_rate ());
+ noutput_items = round_down (noutput_items, m->output_multiple ());
+ LOG(*d_log << " max_items_avail = " << max_items_avail << std::endl);
+ LOG(*d_log << " noutput_items = " << noutput_items << std::endl);
+
+ if (noutput_items == 0){ // we're blocked on input
+ LOG(*d_log << " BLKD_IN\n");
+ goto next_block;
+ }
+
+ goto try_again; // Jump to code shared with regular case.
+ }
+
+ else {
+ // do the regular thing
+ ninput_items_required.resize (d->ninputs ());
+ ninput_items.resize (d->ninputs ());
+ input_items.resize (d->ninputs ());
+ output_items.resize (d->noutputs ());
+
+ max_items_avail = 0;
+ for (int i = 0; i < d->ninputs (); i++){
+ ninput_items[i] = d->input(i)->items_available ();
+ max_items_avail = std::max (max_items_avail, ninput_items[i]);
+ }
+
+ // determine the minimum available output space
+ noutput_items = min_available_space (d, m->output_multiple ());
+ if (ENABLE_LOGGING){
+ *d_log << " regular ";
+ if (m->relative_rate() >= 1.0)
+ *d_log << "1:" << m->relative_rate() << std::endl;
+ else
+ *d_log << 1.0/m->relative_rate() << ":1\n";
+ *d_log << " max_items_avail = " << max_items_avail << std::endl;
+ *d_log << " noutput_items = " << noutput_items << std::endl;
+ }
+ if (noutput_items == -1) // we're done
+ goto were_done;
+
+ if (noutput_items == 0){ // we're output blocked
+ LOG(*d_log << " BLKD_OUT\n");
+ goto next_block;
+ }
+
+#if 0
+ // Compute best estimate of noutput_items that we can really use.
+ noutput_items =
+ std::min ((unsigned) noutput_items,
+ std::max ((unsigned) m->output_multiple(),
+ round_up ((unsigned) (max_items_avail * m->relative_rate()),
+ m->output_multiple ())));
+
+ LOG(*d_log << " revised noutput_items = " << noutput_items << std::endl);
+#endif
+
+ try_again:
+ if (m->fixed_rate()){
+ // try to work it forward starting with max_items_avail.
+ // We want to try to consume all the input we've got.
+ int reqd_noutput_items = m->fixed_rate_ninput_to_noutput(max_items_avail);
+ reqd_noutput_items = round_up(reqd_noutput_items, m->output_multiple());
+ if (reqd_noutput_items > 0 && reqd_noutput_items <= noutput_items)
+ noutput_items = reqd_noutput_items;
+ }
+
+ // ask the block how much input they need to produce noutput_items
+ m->forecast (noutput_items, ninput_items_required);
+
+ // See if we've got sufficient input available
+
+ int i;
+ for (i = 0; i < d->ninputs (); i++)
+ if (ninput_items_required[i] > ninput_items[i]) // not enough
+ break;
+
+ if (i < d->ninputs ()){ // not enough input on input[i]
+ // if we can, try reducing the size of our output request
+ if (noutput_items > m->output_multiple ()){
+ noutput_items /= 2;
+ noutput_items = round_up (noutput_items, m->output_multiple ());
+ goto try_again;
+ }
+
+ // We're blocked on input
+ LOG(*d_log << " BLKD_IN\n");
+ if (d->input(i)->done()) // If the upstream block is done, we're done
+ goto were_done;
+
+ // Is it possible to ever fulfill this request?
+ if (ninput_items_required[i] > d->input(i)->max_possible_items_available ()){
+ // Nope, never going to happen...
+ std::cerr << "\nsched: <gr_block " << m->name()
+ << " (" << m->unique_id() << ")>"
+ << " is requesting more input data\n"
+ << " than we can provide.\n"
+ << " ninput_items_required = "
+ << ninput_items_required[i] << "\n"
+ << " max_possible_items_available = "
+ << d->input(i)->max_possible_items_available() << "\n"
+ << " If this is a filter, consider reducing the number of taps.\n";
+ goto were_done;
+ }
+
+ goto next_block;
+ }
+
+ // We've got enough data on each input to produce noutput_items.
+ // Finish setting up the call to work.
+
+ for (int i = 0; i < d->ninputs (); i++)
+ input_items[i] = d->input(i)->read_pointer();
+
+ setup_call_to_work:
+
+ for (int i = 0; i < d->noutputs (); i++)
+ output_items[i] = d->output(i)->write_pointer();
+
+ // Do the actual work of the block
+ int n = m->general_work (noutput_items, ninput_items,
+ input_items, output_items);
+ LOG(*d_log << " general_work: noutput_items = " << noutput_items
+ << " result = " << n << std::endl);
+
+ if (n == -1) // block is done
+ goto were_done;
+
+ d->produce_each (n); // advance write pointers
+ if (n > 0)
+ making_progress = true;
+
+ goto next_block;
+ }
+ assert (0);
+
+ were_done:
+ LOG(*d_log << " were_done\n");
+ d->set_done (true);
+ nalive--;
+
+ next_block:
+ if (++bi >= d_blocks.size ()){
+ bi = 0;
+ made_progress_last_pass = making_progress;
+ making_progress = false;
+ }
+ }
+
+ for (unsigned i = 0; i < d_blocks.size (); i++) // disable any drivers, etc.
+ d_blocks[i]->stop();
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.h b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.h
new file mode 100644
index 0000000000..1272831e59
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_SINGLE_THREADED_SCHEDULER_H
+#define INCLUDED_GR_SINGLE_THREADED_SCHEDULER_H
+
+#include <gr_runtime.h>
+#include <fstream>
+
+class gr_single_threaded_scheduler;
+typedef boost::shared_ptr<gr_single_threaded_scheduler> gr_single_threaded_scheduler_sptr;
+
+
+/*!
+ * \brief Simple scheduler for stream computations.
+ * \ingroup internal
+ */
+
+class gr_single_threaded_scheduler {
+ public:
+ ~gr_single_threaded_scheduler ();
+
+ void run ();
+ void stop () { d_enabled = false; }
+
+ private:
+ const std::vector<gr_block_sptr> d_blocks;
+ volatile bool d_enabled;
+ std::ofstream *d_log;
+
+ gr_single_threaded_scheduler (const std::vector<gr_block_sptr> &blocks);
+
+ void main_loop ();
+
+ friend gr_single_threaded_scheduler_sptr
+ gr_make_single_threaded_scheduler (const std::vector<gr_block_sptr> &blocks);
+};
+
+gr_single_threaded_scheduler_sptr
+gr_make_single_threaded_scheduler (const std::vector<gr_block_sptr> &blocks);
+
+#endif /* INCLUDED_GR_SINGLE_THREADED_SCHEDULER_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.i b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.i
new file mode 100644
index 0000000000..40058228b2
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.i
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gr_runtime.h>
+
+class gr_single_threaded_scheduler;
+typedef boost::shared_ptr<gr_single_threaded_scheduler> gr_single_threaded_scheduler_sptr;
+%template(gr_single_threaded_scheduler_sptr) boost::shared_ptr<gr_single_threaded_scheduler>;
+%rename(single_threaded_scheduler) gr_make_single_threaded_scheduler;
+%ignore gr_single_threaded_scheduler;
+
+gr_single_threaded_scheduler_sptr
+gr_make_single_threaded_scheduler (const std::vector<gr_block_sptr> &modules);
+
+class gr_single_threaded_scheduler {
+ public:
+ ~gr_single_threaded_scheduler ();
+
+ // void run ();
+ void stop ();
+
+ private:
+ gr_single_threaded_scheduler (const std::vector<gr_block_sptr> &modules);
+};
+
+%inline {
+ void sts_pyrun (gr_single_threaded_scheduler_sptr s) {
+ Py_BEGIN_ALLOW_THREADS; // release global interpreter lock
+ s->run ();
+ Py_END_ALLOW_THREADS; // acquire global interpreter lock
+ }
+}
+
diff --git a/gnuradio-core/src/lib/runtime/gr_swig_block_magic.i b/gnuradio-core/src/lib/runtime/gr_swig_block_magic.i
new file mode 100644
index 0000000000..ca4f6e600d
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_swig_block_magic.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+%define GR_SWIG_BLOCK_MAGIC(PKG, BASE_NAME)
+_GR_SWIG_BLOCK_MAGIC_HELPER(PKG, PKG ## _ ## BASE_NAME, BASE_NAME)
+%enddef
+
+%define _GR_SWIG_BLOCK_MAGIC_HELPER(PKG, NAME, BASE_NAME)
+class NAME;
+typedef boost::shared_ptr<NAME> NAME ## _sptr;
+%template(NAME ## _sptr) boost::shared_ptr<NAME>;
+%rename(BASE_NAME) PKG ## _make_ ## BASE_NAME;
+%inline {
+ gr_block_sptr NAME ## _block (NAME ## _sptr r)
+ {
+ return gr_block_sptr (r);
+ }
+}
+
+%pythoncode %{
+NAME ## _sptr.block = lambda self: NAME ## _block (self)
+NAME ## _sptr.__repr__ = lambda self: "<gr_block %s (%d)>" % (self.name(), self.unique_id ())
+%}
+
+%ignore NAME;
+%enddef
diff --git a/gnuradio-core/src/lib/runtime/gr_timer.h b/gnuradio-core/src/lib/runtime/gr_timer.h
new file mode 100644
index 0000000000..709b98470e
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_timer.h
@@ -0,0 +1,82 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_TIMER_H
+#define INCLUDED_GR_TIMER_H
+
+#include <gr_types.h>
+
+class gr_timer;
+
+typedef boost::shared_ptr<gr_timer> gr_timer_sptr;
+
+typedef void (*gr_timer_hook)(gr_timer *, void *);
+
+/*!
+ * \brief create a timeout.
+ *
+ * gr_timer_hook is called when timer fires.
+ */
+gr_timer_sptr gr_make_timer (gr_timer_hook, void *);
+
+/*!
+ * \brief implement timeouts
+ */
+class gr_timer {
+ double d_expiry;
+ double d_period;
+ gr_timer_hook d_hook;
+ void *d_hook_arg;
+
+ friend gr_timer_sptr gr_make_timer (gr_timer_hook, void *);
+
+ gr_timer (...);
+
+public:
+ ~gr_timer ();
+
+ //! return absolute current time (seconds since the epoc).
+ static double now ();
+
+ /*!
+ * \brief schedule timer to fire at abs_when
+ * \param abs_when absolute time in seconds since the epoc.
+ */
+ void schedule_at (double abs_when);
+
+ /*!
+ * \brief schedule timer to fire rel_when seconds from now.
+ * \param rel_when relative time in seconds from now.
+ */
+ void schedule_after (double rel_when); // relative time in seconds
+
+ /*!
+ * \brief schedule a periodic timeout.
+ * \param abs_when absolute time to fire first time
+ * \param period time between firings
+ */
+ void schedule_periodic (double abs_when, double period);
+
+ //! cancel timer
+ void unschedule ();
+};
+
+#endif /* INCLUDED_GR_TIMER_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_tmp_path.cc b/gnuradio-core/src/lib/runtime/gr_tmp_path.cc
new file mode 100644
index 0000000000..7eb03b5d55
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_tmp_path.cc
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gr_tmp_path.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+const char *
+gr_tmp_path ()
+{
+ static char *pp = 0;
+
+ if (pp)
+ return pp;
+
+ char *s = getenv ("TMP");
+ if (s){
+ pp = strdup (s);
+ return pp;
+ }
+
+#ifdef P_tmpdir
+ if (P_tmpdir){
+ pp = strdup (P_tmpdir);
+ return pp;
+ }
+#endif
+
+ pp = strdup ("/tmp");
+ return pp;
+}
+
diff --git a/gnuradio-core/src/lib/runtime/gr_tmp_path.h b/gnuradio-core/src/lib/runtime/gr_tmp_path.h
new file mode 100644
index 0000000000..742ce05633
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_tmp_path.h
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GR_TMP_PATH_H_
+#define _GR_TMP_PATH_H_
+
+/*!
+ * \brief return directory portion of pathname used for temporary files.
+ */
+const char *gr_tmp_path ();
+
+#endif /* _GR_TMP_PATH_H_ */
diff --git a/gnuradio-core/src/lib/runtime/gr_types.h b/gnuradio-core/src/lib/runtime/gr_types.h
new file mode 100644
index 0000000000..370ca56424
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_types.h
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_TYPES_H
+#define INCLUDED_GR_TYPES_H
+
+#include <boost/shared_ptr.hpp>
+#include <vector>
+#include <stddef.h> // size_t
+
+#include <gr_complex.h>
+
+typedef std::vector<int> gr_vector_int;
+typedef std::vector<float> gr_vector_float;
+typedef std::vector<double> gr_vector_double;
+typedef std::vector<void *> gr_vector_void_star;
+typedef std::vector<const void *> gr_vector_const_void_star;
+
+/*
+ * #include <config.h> must be placed beforehand
+ * in the source file including gr_types.h for
+ * the following to work correctly
+ */
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+typedef int16_t gr_int16;
+typedef int32_t gr_int32;
+typedef int64_t gr_int64;
+typedef uint16_t gr_uint16;
+typedef uint32_t gr_uint32;
+typedef uint64_t gr_uint64;
+#else
+/*
+ * Note: these defaults may be wrong on 64-bit systems
+ */
+typedef short gr_int16;
+typedef int gr_int32;
+typedef long long gr_int64;
+typedef unsigned short gr_uint16;
+typedef unsigned int gr_uint32;
+typedef unsigned long long gr_uint64;
+#endif /* HAVE_STDINT_H */
+
+#endif /* INCLUDED_GR_TYPES_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf.cc b/gnuradio-core/src/lib/runtime/gr_vmcircbuf.cc
new file mode 100644
index 0000000000..3586c4c73d
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf.cc
@@ -0,0 +1,291 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_vmcircbuf.h>
+#include <assert.h>
+#include <stdexcept>
+#include <gr_preferences.h>
+#include <stdio.h>
+#include <gr_local_sighandler.h>
+
+// all the factories we know about
+#include <gr_vmcircbuf_createfilemapping.h>
+#include <gr_vmcircbuf_sysv_shm.h>
+#include <gr_vmcircbuf_mmap_shm_open.h>
+#include <gr_vmcircbuf_mmap_tmpfile.h>
+
+static const char *FACTORY_PREF_KEY = "gr_vmcircbuf_default_factory";
+
+gr_vmcircbuf::~gr_vmcircbuf ()
+{
+}
+
+gr_vmcircbuf_factory::~gr_vmcircbuf_factory ()
+{
+}
+
+// ----------------------------------------------------------------
+
+static gr_vmcircbuf_factory *s_default_factory = 0;
+
+gr_vmcircbuf_factory *
+gr_vmcircbuf_sysconfig::get_default_factory ()
+{
+ if (s_default_factory)
+ return s_default_factory;
+
+ bool verbose = false;
+
+ std::vector<gr_vmcircbuf_factory *> all = all_factories ();
+
+ const char *name = gr_preferences::get (FACTORY_PREF_KEY);
+
+ if (name){
+ for (unsigned int i = 0; i < all.size (); i++){
+ if (strcmp (name, all[i]->name ()) == 0){
+ s_default_factory = all[i];
+ if (verbose)
+ fprintf (stderr, "gr_vmcircbuf_sysconfig: using %s\n",
+ s_default_factory->name ());
+ return s_default_factory;
+ }
+ }
+ }
+
+ // either we don't have a default, or the default named is not in our
+ // list of factories. Find the first factory that works.
+
+ if (verbose)
+ fprintf (stderr, "gr_vmcircbuf_sysconfig: finding a working factory...\n");
+
+ for (unsigned int i = 0; i < all.size (); i++){
+ if (test_factory (all[i], verbose)){
+ set_default_factory (all[i]);
+ return s_default_factory;
+ }
+ }
+
+ // We're screwed!
+
+ fprintf (stderr, "gr_vmcircbuf_sysconfig: unable to find a working factory!\n");
+ throw std::runtime_error ("gr_vmcircbuf_sysconfig");
+}
+
+std::vector<gr_vmcircbuf_factory *>
+gr_vmcircbuf_sysconfig::all_factories ()
+{
+ std::vector<gr_vmcircbuf_factory *> result;
+
+ result.push_back (gr_vmcircbuf_createfilemapping_factory::singleton ());
+ result.push_back (gr_vmcircbuf_sysv_shm_factory::singleton ());
+ result.push_back (gr_vmcircbuf_mmap_shm_open_factory::singleton ());
+ result.push_back (gr_vmcircbuf_mmap_tmpfile_factory::singleton ());
+
+ return result;
+}
+
+void
+gr_vmcircbuf_sysconfig::set_default_factory (gr_vmcircbuf_factory *f)
+{
+ gr_preferences::set (FACTORY_PREF_KEY, f->name ());
+ s_default_factory = f;
+}
+
+
+// ------------------------------------------------------------------------
+// test code for vmcircbuf factories
+// ------------------------------------------------------------------------
+
+static void
+init_buffer (gr_vmcircbuf *c, int counter, int size)
+{
+ unsigned int *p = (unsigned int *) c->pointer_to_first_copy ();
+ for (unsigned int i = 0; i < size / sizeof (int); i++)
+ p[i] = counter + i;
+}
+
+static bool
+check_mapping (gr_vmcircbuf *c, int counter, int size, char *msg, bool verbose)
+{
+ bool ok = true;
+
+ if (verbose)
+ fprintf (stderr, "... %s", msg);
+
+ unsigned int *p1 = (unsigned int *) c->pointer_to_first_copy ();
+ unsigned int *p2 = (unsigned int *) c->pointer_to_second_copy ();
+
+ // fprintf (stderr, "p1 = %p, p2 = %p\n", p1, p2);
+
+ for (unsigned int i = 0; i < size / sizeof (int); i++){
+ if (p1[i] != counter + i){
+ ok = false;
+ if (verbose)
+ fprintf (stderr, " p1[%d] == %u, expected %u\n", i, p1[i], counter + i);
+ break;
+ }
+ if (p2[i] != counter + i){
+ if (verbose)
+ fprintf (stderr, " p2[%d] == %u, expected %u\n", i, p2[i], counter + i);
+ ok = false;
+ break;
+ }
+ }
+
+ if (ok && verbose){
+ fprintf (stderr, " OK\n");
+ }
+ return ok;
+}
+
+static char *
+memsize (int size)
+{
+ static char buf[100];
+ if (size >= (1 << 20)){
+ snprintf (buf, sizeof (buf), "%dMB", size / (1 << 20));
+ }
+ else if (size >= (1 << 10)){
+ snprintf (buf, sizeof (buf), "%dKB", size / (1 << 10));
+ }
+ else {
+ snprintf (buf, sizeof (buf), "%d", size);
+ }
+ return buf;
+}
+
+static bool
+test_a_bunch (gr_vmcircbuf_factory *factory, int n, int size, int *start_ptr, bool verbose)
+{
+ bool ok = true;
+ int counter[n];
+ gr_vmcircbuf *c[n];
+ int cum_size = 0;
+
+ for (int i = 0; i < n; i++){
+ counter[i] = *start_ptr;
+ *start_ptr += size;
+ if ((c[i] = factory->make (size)) == 0){
+ if (verbose)
+ fprintf (stderr,
+ "Failed to allocate gr_vmcircbuf number %d of size %d (cum = %s)\n",
+ i + 1, size, memsize (cum_size));
+ return false;
+ }
+ init_buffer (c[i], counter[i], size);
+ cum_size += size;
+ }
+
+ for (int i = 0; i < n; i++){
+ char msg[100];
+ snprintf (msg, sizeof (msg), "test_a_bunch_%dx%s[%d]", n, memsize (size), i);
+ ok &= check_mapping (c[i], counter[i], size, msg, verbose);
+ }
+
+ for (int i = 0; i < n; i++){
+ delete c[i];
+ c[i] = 0;
+ }
+
+ return ok;
+}
+
+static bool
+standard_tests (gr_vmcircbuf_factory *f, int verbose)
+{
+ if (verbose >= 1)
+ fprintf (stderr, "Testing %s...\n", f->name ());
+
+ bool v = verbose >= 2;
+ int granularity = f->granularity ();
+ int start = 0;
+ bool ok = true;
+
+ ok &= test_a_bunch (f, 1, 1 * granularity, &start, v); // 1 x 4KB = 4KB
+
+ if (ok){
+ ok &= test_a_bunch (f, 64, 4 * granularity, &start, v); // 256 x 16KB = 4MB
+ ok &= test_a_bunch (f, 32, 4 * (1L << 20), &start, v); // 32 x 4MB = 64MB
+ ok &= test_a_bunch (f, 256, 256 * (1L << 10), &start, v); // 256 x 256KB = 64MB
+ }
+
+ if (verbose >= 1)
+ fprintf (stderr, "....... %s: %s", f->name (), ok ? "OK\n" : "Doesn't work\n");
+
+ return ok;
+}
+
+bool
+gr_vmcircbuf_sysconfig::test_factory (gr_vmcircbuf_factory *f, int verbose)
+{
+ // Install local signal handlers for SIGSEGV and SIGBUS.
+ // If something goes wrong, these signals may be invoked.
+
+#ifdef SIGSEGV
+ gr_local_sighandler sigsegv (SIGSEGV, gr_local_sighandler::throw_signal);
+#endif
+#ifdef SIGBUS
+ gr_local_sighandler sigbus (SIGBUS, gr_local_sighandler::throw_signal);
+#endif
+#ifdef SIGSYS
+ gr_local_sighandler sigsys (SIGSYS, gr_local_sighandler::throw_signal);
+#endif
+
+ try {
+ return standard_tests (f, verbose);
+ }
+ catch (gr_signal &sig){
+ if (verbose){
+ fprintf (stderr, "....... %s: %s", f->name (), "Doesn't work\n");
+ fprintf (stderr,
+ "gr_vmcircbuf_factory::test_factory (%s): caught %s\n",
+ f->name (), sig.name().c_str());
+ return false;
+ }
+ }
+ catch (...){
+ if (verbose){
+ fprintf (stderr, "....... %s: %s", f->name (), "Doesn't work\n");
+ fprintf (stderr,
+ "gr_vmcircbuf_factory::test_factory (%s): some kind of uncaught exception\n",
+ f->name ());
+ }
+ return false;
+ }
+ return false; // never gets here. shut compiler up.
+}
+
+bool
+gr_vmcircbuf_sysconfig::test_all_factories (int verbose)
+{
+ bool ok = false;
+
+ std::vector<gr_vmcircbuf_factory *> all = all_factories ();
+
+ for (unsigned int i = 0; i < all.size (); i++)
+ ok |= test_factory (all[i], verbose);
+
+ return ok;
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf.h b/gnuradio-core/src/lib/runtime/gr_vmcircbuf.h
new file mode 100644
index 0000000000..e2af935877
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf.h
@@ -0,0 +1,120 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GR_VMCIRCBUF_H_
+#define _GR_VMCIRCBUF_H_
+
+#include <vector>
+
+/*!
+ * \brief abstract class to implement doubly mapped virtual memory circular buffers
+ */
+class gr_vmcircbuf {
+ protected:
+ int d_size;
+ char *d_base;
+
+ // CREATORS
+ gr_vmcircbuf (int size) : d_size (size), d_base (0) {};
+
+ public:
+ virtual ~gr_vmcircbuf ();
+
+ // ACCESSORS
+ void *pointer_to_first_copy () const { return d_base; }
+ void *pointer_to_second_copy () const { return d_base + d_size; }
+};
+
+/*!
+ * \brief abstract factory for creating circular buffers
+ */
+class gr_vmcircbuf_factory {
+ protected:
+ gr_vmcircbuf_factory () {};
+ virtual ~gr_vmcircbuf_factory ();
+
+ public:
+
+ /*!
+ * \brief return name of this factory
+ */
+ virtual const char *name () const = 0;
+
+ /*!
+ * \brief return granularity of mapping, typically equal to page size
+ */
+ virtual int granularity () = 0;
+
+ /*!
+ * \brief return a gr_vmcircbuf, or 0 if unable.
+ *
+ * Call this to create a doubly mapped circular buffer.
+ */
+ virtual gr_vmcircbuf *make (int size) = 0;
+};
+
+/*
+ * \brief pulls together all implementations of gr_vmcircbuf
+ */
+class gr_vmcircbuf_sysconfig {
+ public:
+
+ /*
+ * \brief return the single instance of the default factory.
+ *
+ * returns the default factory to use if it's already defined,
+ * else find the first working factory and use it.
+ */
+ static gr_vmcircbuf_factory *get_default_factory ();
+
+
+ static int granularity () { return get_default_factory()->granularity(); }
+ static gr_vmcircbuf *make (int size) { return get_default_factory()->make(size); }
+
+
+ // N.B. not all factories are guaranteed to work.
+ // It's too hard to check everything at config time, so we check at runtime
+ static std::vector<gr_vmcircbuf_factory *> all_factories ();
+
+ // make this factory the default
+ static void set_default_factory (gr_vmcircbuf_factory *f);
+
+ /*!
+ * \brief Does this factory really work?
+ *
+ * verbose = 0: silent
+ * verbose = 1: names of factories tested and results
+ * verbose = 2: all intermediate results
+ */
+ static bool test_factory (gr_vmcircbuf_factory *f, int verbose);
+
+ /*!
+ * \brief Test all factories, return true if at least one of them works
+ * verbose = 0: silent
+ * verbose = 1: names of factories tested and results
+ * verbose = 2: all intermediate results
+ */
+ static bool test_all_factories (int verbose);
+};
+
+
+#endif /* _GR_VMCIRCBUF_H_ */
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.cc b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.cc
new file mode 100644
index 0000000000..8f3540b4b4
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.cc
@@ -0,0 +1,191 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdexcept>
+#include <assert.h>
+#include <unistd.h>
+#include <fcntl.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#include <errno.h>
+#include <stdio.h>
+#include <gr_pagesize.h>
+#include <gr_tmp_path.h>
+#include <gr_vmcircbuf_createfilemapping.h>
+
+
+gr_vmcircbuf_createfilemapping::gr_vmcircbuf_createfilemapping (int size)
+ : gr_vmcircbuf (size)
+{
+#if !defined(HAVE_CREATEFILEMAPPING)
+ fprintf (stderr, "%s: createfilemapping is not available\n",__FUNCTION__);
+ throw std::runtime_error ("gr_vmcircbuf_createfilemapping");
+#else
+ static int s_seg_counter = 0;
+
+ if (size <= 0 || (size % gr_pagesize ()) != 0){
+ fprintf (stderr, "gr_vmcircbuf_createfilemapping: invalid size = %d\n", size);
+ throw std::runtime_error ("gr_vmcircbuf_createfilemapping");
+ }
+
+ char seg_name[1024];
+ snprintf (seg_name, sizeof (seg_name), "/gnuradio-%d-%d", getpid (), s_seg_counter);
+
+ d_handle = CreateFileMapping(INVALID_HANDLE_VALUE, // use paging file
+ NULL, // default security
+ PAGE_READWRITE, // read/write access
+ 0, // max. object size
+ size, // buffer size
+ seg_name); // name of mapping object
+
+ s_seg_counter++;
+ if (d_handle == NULL || d_handle == INVALID_HANDLE_VALUE){
+ char msg[1024];
+ snprintf (msg, sizeof (msg), "gr_vmcircbuf_mmap_createfilemapping: CreateFileMapping [%s] :%d", seg_name,(int)GetLastError());
+ perror (msg);
+ throw std::runtime_error ("gr_vmcircbuf_mmap_createfilemapping");
+ }
+
+ int i = 0;
+ d_first_copy = d_second_copy = NULL;
+
+ while (i++ < 8 && d_second_copy == NULL){
+ // keep the first map allocation to force allocation in a new address
+ // space
+ LPVOID first_tmp = d_first_copy;
+
+ d_first_copy = MapViewOfFile((HANDLE)d_handle, // handle to map object
+ FILE_MAP_WRITE, // read/write permission
+ 0,
+ 0,
+ size);
+
+ if (d_first_copy == NULL){
+ if (first_tmp)
+ UnmapViewOfFile(first_tmp);
+
+ CloseHandle(d_handle); // cleanup
+ char msg[1024];
+ snprintf (msg, sizeof (msg),
+ "gr_vmcircbuf_mmap_createfilemapping: MapViewOfFile (1) :%d", (int)GetLastError());
+ perror (msg);
+ throw std::runtime_error ("gr_vmcircbuf_mmap_createfilemapping");
+ }
+
+ // NOTE: d_second_copy will be NULL if MapViewFileEx() fails to allocate the
+ // requested address space
+ d_second_copy = MapViewOfFileEx((HANDLE)d_handle, // handle to map object
+ FILE_MAP_WRITE, // read/write permission
+ 0,
+ 0,
+ size,
+ (char *)d_first_copy + size);//(LPVOID) ((char *)d_first_copy + size));
+
+ if (first_tmp)
+ UnmapViewOfFile(first_tmp);
+
+#ifdef DEBUG
+ fprintf (stderr,"gr_vmcircbuf_mmap_createfilemapping: contiguous? mmap %p %p %p %p, %d\n",
+ (char *)d_first_copy, (char *)d_second_copy, size, (char *)d_first_copy + size,i);
+#endif
+ }
+
+ if (d_second_copy == NULL){ // cleanup
+ fprintf (stderr,"gr_vmcircbuf_mmap_createfilemapping: non contiguous mmap - %p %p %p %p\n",
+ d_first_copy, d_second_copy, size, (char *)d_first_copy + size);
+ UnmapViewOfFile(d_first_copy);
+ CloseHandle(d_handle); // cleanup
+ throw std::runtime_error ("gr_vmcircbuf_mmap_createfilemapping");
+ }
+
+ // Now remember the important stuff
+ d_base = (char *) d_first_copy;
+ d_size = size;
+#endif /*HAVE_CREATEFILEMAPPING*/
+}
+
+gr_vmcircbuf_createfilemapping::~gr_vmcircbuf_createfilemapping ()
+{
+#ifdef HAVE_CREATEFILEMAPPING
+ if (UnmapViewOfFile(d_first_copy) == 0)
+ {
+ perror ("gr_vmcircbuf_createfilemapping: UnmapViewOfFile(d_first_copy)");
+ }
+ d_base=NULL;
+ if (UnmapViewOfFile(d_second_copy) == 0)
+ {
+ perror ("gr_vmcircbuf_createfilemapping: UnmapViewOfFile(d_second_copy)");
+ }
+ //d_second=NULL;
+ CloseHandle(d_handle);
+#endif
+}
+
+// ----------------------------------------------------------------
+// The factory interface
+// ----------------------------------------------------------------
+
+
+gr_vmcircbuf_factory *gr_vmcircbuf_createfilemapping_factory::s_the_factory = 0;
+
+gr_vmcircbuf_factory *
+gr_vmcircbuf_createfilemapping_factory::singleton ()
+{
+ if (s_the_factory)
+ return s_the_factory;
+ s_the_factory = new gr_vmcircbuf_createfilemapping_factory ();
+ return s_the_factory;
+}
+
+int
+gr_vmcircbuf_createfilemapping_factory::granularity ()
+{
+#ifdef HAVE_CREATEFILEMAPPING
+ // return 65536;//TODO, check, is this needed or can we just use gr_pagesize()
+ SYSTEM_INFO system_info;
+ GetSystemInfo(&system_info);
+ //fprintf(stderr,"win32 AllocationGranularity %p\n",(int)system_info.dwAllocationGranularity);
+ return (int)system_info.dwAllocationGranularity;
+#else
+ return gr_pagesize ();
+#endif
+}
+
+gr_vmcircbuf *
+gr_vmcircbuf_createfilemapping_factory::make (int size)
+{
+ try
+ {
+ return new gr_vmcircbuf_createfilemapping (size);
+ }
+ catch (...)
+ {
+ return 0;
+ }
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.h b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.h
new file mode 100644
index 0000000000..f7113cf4fd
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.h
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GR_VMCIRCBUF_CREATEFILEMAPPING_H_
+#define _GR_VMCIRCBUF_CREATEFILEMAPPING_H_
+
+#include <gr_vmcircbuf.h>
+
+#ifdef HAVE_CREATEFILEMAPPING
+#include <windows.h>
+#endif
+/*!
+ * \brief concrete class to implement circular buffers with mmap and shm_open
+ */
+class gr_vmcircbuf_createfilemapping : public gr_vmcircbuf
+{
+ public:
+ // CREATORS
+ gr_vmcircbuf_createfilemapping (int size);
+ virtual ~gr_vmcircbuf_createfilemapping ();
+#ifdef HAVE_CREATEFILEMAPPING
+ private:
+ HANDLE d_handle;
+ LPVOID d_first_copy;
+ LPVOID d_second_copy;
+#endif
+};
+
+/*!
+ * \brief concrete factory for circular buffers built using mmap and shm_open
+ */
+class gr_vmcircbuf_createfilemapping_factory : public gr_vmcircbuf_factory
+{
+ private:
+ static gr_vmcircbuf_factory *s_the_factory;
+
+ public:
+ static gr_vmcircbuf_factory *singleton ();
+
+ virtual const char *name () const { return "gr_vmcircbuf_createfilemapping_factory"; }
+
+ /*!
+ * \brief return granularity of mapping, typically equal to page size
+ */
+ virtual int granularity ();
+
+ /*!
+ * \brief return a gr_vmcircbuf, or 0 if unable.
+ *
+ * Call this to create a doubly mapped circular buffer.
+ */
+ virtual gr_vmcircbuf *make (int size);
+};
+
+#endif /* _GR_VMCIRCBUF_CREATEFILEMAPPING_H_ */
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.cc b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.cc
new file mode 100644
index 0000000000..65fa1183b4
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.cc
@@ -0,0 +1,205 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_vmcircbuf_mmap_shm_open.h>
+#include <stdexcept>
+#include <assert.h>
+#include <unistd.h>
+#include <fcntl.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#include <errno.h>
+#include <stdio.h>
+#include <gr_pagesize.h>
+#include <gr_tmp_path.h>
+
+
+gr_vmcircbuf_mmap_shm_open::gr_vmcircbuf_mmap_shm_open (int size)
+ : gr_vmcircbuf (size)
+{
+#if !defined(HAVE_MMAP) || !defined(HAVE_SHM_OPEN)
+ fprintf (stderr, "gr_vmcircbuf_mmap_shm_open: mmap or shm_open is not available\n");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+#else
+ static int s_seg_counter = 0;
+
+ if (size <= 0 || (size % gr_pagesize ()) != 0){
+ fprintf (stderr, "gr_vmcircbuf_mmap_shm_open: invalid size = %d\n", size);
+ throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+ }
+
+ int shm_fd = -1;
+ char seg_name[1024];
+ static bool portable_format = true;
+
+ // open a new named shared memory segment
+
+ while (1){
+ if (portable_format){
+
+ // This is the POSIX recommended "portable format".
+ // Of course the "portable format" doesn't work on some systems...
+
+ snprintf (seg_name, sizeof (seg_name),
+ "/gnuradio-%d-%d", getpid (), s_seg_counter);
+ }
+ else {
+
+ // Where the "portable format" doesn't work, we try building
+ // a full filesystem pathname pointing into a suitable temporary directory.
+
+ snprintf (seg_name, sizeof (seg_name),
+ "%s/gnuradio-%d-%d", gr_tmp_path (), getpid (), s_seg_counter);
+ }
+
+ shm_fd = shm_open (seg_name, O_RDWR | O_CREAT | O_EXCL, 0600);
+ if (shm_fd == -1 && errno == EACCES && portable_format){
+ portable_format = false;
+ continue; // try again using "non-portable format"
+ }
+
+ s_seg_counter++;
+
+ if (shm_fd == -1){
+ if (errno == EEXIST) // Named segment already exists (shouldn't happen). Try again
+ continue;
+
+ char msg[1024];
+ snprintf (msg, sizeof (msg), "gr_vmcircbuf_mmap_shm_open: shm_open [%s]", seg_name);
+ perror (msg);
+ throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+ }
+ break;
+ }
+
+ // We've got a new shared memory segment fd open.
+ // Now set it's length to 2x what we really want and mmap it in.
+
+ if (ftruncate (shm_fd, (off_t) 2 * size) == -1){
+ close (shm_fd); // cleanup
+ perror ("gr_vmcircbuf_mmap_shm_open: ftruncate (1)");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+ }
+
+ void *first_copy = mmap (0, 2 * size,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ shm_fd, (off_t) 0);
+
+ if (first_copy == MAP_FAILED){
+ close (shm_fd); // cleanup
+ perror ("gr_vmcircbuf_mmap_shm_open: mmap (1)");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+ }
+
+ // unmap the 2nd half
+ if (munmap ((char *) first_copy + size, size) == -1){
+ close (shm_fd); // cleanup
+ perror ("gr_vmcircbuf_mmap_shm_open: munmap (1)");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+ }
+
+ // map the first half into the now available hole where the
+ // second half used to be.
+
+ void *second_copy = mmap ((char *) first_copy + size, size,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ shm_fd, (off_t) 0);
+
+ if (second_copy == MAP_FAILED){
+ close (shm_fd); // cleanup
+ perror ("gr_vmcircbuf_mmap_shm_open: mmap (2)");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+ }
+
+#if 0 // OS/X doesn't allow you to resize the segment
+
+ // cut the shared memory segment down to size
+ if (ftruncate (shm_fd, (off_t) size) == -1){
+ close (shm_fd); // cleanup
+ perror ("gr_vmcircbuf_mmap_shm_open: ftruncate (2)");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+ }
+#endif
+
+ close (shm_fd); // fd no longer needed. The mapping is retained.
+
+ if (shm_unlink (seg_name) == -1){ // unlink the seg_name.
+ perror ("gr_vmcircbuf_mmap_shm_open: shm_unlink");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+ }
+
+ // Now remember the important stuff
+
+ d_base = (char *) first_copy;
+ d_size = size;
+#endif
+}
+
+gr_vmcircbuf_mmap_shm_open::~gr_vmcircbuf_mmap_shm_open ()
+{
+#if defined(HAVE_MMAP)
+ if (munmap (d_base, 2 * d_size) == -1){
+ perror ("gr_vmcircbuf_mmap_shm_open: munmap (2)");
+ }
+#endif
+}
+
+// ----------------------------------------------------------------
+// The factory interface
+// ----------------------------------------------------------------
+
+
+gr_vmcircbuf_factory *gr_vmcircbuf_mmap_shm_open_factory::s_the_factory = 0;
+
+gr_vmcircbuf_factory *
+gr_vmcircbuf_mmap_shm_open_factory::singleton ()
+{
+ if (s_the_factory)
+ return s_the_factory;
+
+ s_the_factory = new gr_vmcircbuf_mmap_shm_open_factory ();
+ return s_the_factory;
+}
+
+int
+gr_vmcircbuf_mmap_shm_open_factory::granularity ()
+{
+ return gr_pagesize ();
+}
+
+gr_vmcircbuf *
+gr_vmcircbuf_mmap_shm_open_factory::make (int size)
+{
+ try {
+ return new gr_vmcircbuf_mmap_shm_open (size);
+ }
+ catch (...){
+ return 0;
+ }
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.h b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.h
new file mode 100644
index 0000000000..4b1feafff2
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.h
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GR_VMCIRCBUF_MMAP_SHM_OPEN_H_
+#define _GR_VMCIRCBUF_MMAP_SHM_OPEN_H_
+
+#include <gr_vmcircbuf.h>
+
+/*!
+ * \brief concrete class to implement circular buffers with mmap and shm_open
+ */
+class gr_vmcircbuf_mmap_shm_open : public gr_vmcircbuf {
+ public:
+
+ // CREATORS
+
+ gr_vmcircbuf_mmap_shm_open (int size);
+ virtual ~gr_vmcircbuf_mmap_shm_open ();
+};
+
+/*!
+ * \brief concrete factory for circular buffers built using mmap and shm_open
+ */
+class gr_vmcircbuf_mmap_shm_open_factory : public gr_vmcircbuf_factory {
+ private:
+ static gr_vmcircbuf_factory *s_the_factory;
+
+ public:
+ static gr_vmcircbuf_factory *singleton ();
+
+ virtual const char *name () const { return "gr_vmcircbuf_mmap_shm_open_factory"; }
+
+ /*!
+ * \brief return granularity of mapping, typically equal to page size
+ */
+ virtual int granularity ();
+
+ /*!
+ * \brief return a gr_vmcircbuf, or 0 if unable.
+ *
+ * Call this to create a doubly mapped circular buffer.
+ */
+ virtual gr_vmcircbuf *make (int size);
+};
+
+#endif /* _GR_VMCIRCBUF_MMAP_SHM_OPEN_H_ */
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.cc b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.cc
new file mode 100644
index 0000000000..a07df779c0
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.cc
@@ -0,0 +1,198 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_vmcircbuf_mmap_tmpfile.h>
+#include <stdexcept>
+#include <assert.h>
+#include <unistd.h>
+#include <stdlib.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <gr_pagesize.h>
+#include <gr_tmp_path.h>
+
+
+gr_vmcircbuf_mmap_tmpfile::gr_vmcircbuf_mmap_tmpfile (int size)
+ : gr_vmcircbuf (size)
+{
+#if !defined(HAVE_MMAP)
+ fprintf (stderr, "gr_vmcircbuf_mmap_tmpfile: mmap or mkstemp is not available\n");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+#else
+
+ if (size <= 0 || (size % gr_pagesize ()) != 0){
+ fprintf (stderr, "gr_vmcircbuf_mmap_tmpfile: invalid size = %d\n", size);
+ throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+ }
+
+ int seg_fd = -1;
+ char seg_name[1024];
+
+ static int s_seg_counter = 0;
+
+
+ // open a temporary file that we'll map in a bit later
+
+ while (1){
+ snprintf (seg_name, sizeof (seg_name),
+ "%s/gnuradio-%d-%d-XXXXXX", gr_tmp_path (), getpid (), s_seg_counter);
+ s_seg_counter++;
+
+ seg_fd = open (seg_name, O_RDWR | O_CREAT | O_EXCL, 0600);
+ if (seg_fd == -1){
+ if (errno == EEXIST) // File already exists (shouldn't happen). Try again
+ continue;
+
+ char msg[1024];
+ snprintf (msg, sizeof (msg),
+ "gr_vmcircbuf_mmap_tmpfile: open [%s]", seg_name);
+ perror (msg);
+ throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+ }
+ break;
+ }
+
+ if (unlink (seg_name) == -1){
+ perror ("gr_vmcircbuf_mmap_tmpfile: unlink");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+ }
+
+ // We've got a valid file descriptor to a tmp file.
+ // Now set it's length to 2x what we really want and mmap it in.
+
+ if (ftruncate (seg_fd, (off_t) 2 * size) == -1){
+ close (seg_fd); // cleanup
+ perror ("gr_vmcircbuf_mmap_tmpfile: ftruncate (1)");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+ }
+
+ void *first_copy = mmap (0, 2 * size,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ seg_fd, (off_t) 0);
+
+ if (first_copy == MAP_FAILED){
+ close (seg_fd); // cleanup
+ perror ("gr_vmcircbuf_mmap_tmpfile: mmap (1)");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+ }
+
+ // unmap the 2nd half
+ if (munmap ((char *) first_copy + size, size) == -1){
+ close (seg_fd); // cleanup
+ perror ("gr_vmcircbuf_mmap_tmpfile: munmap (1)");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+ }
+
+ // map the first half into the now available hole where the
+ // second half used to be.
+
+ void *second_copy = mmap ((char *) first_copy + size, size,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ seg_fd, (off_t) 0);
+
+ if (second_copy == MAP_FAILED){
+ munmap(first_copy, size); // cleanup
+ close (seg_fd);
+ perror ("gr_vmcircbuf_mmap_tmpfile: mmap (2)");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+ }
+
+ // check for contiguity
+ if ((char *) second_copy != (char *) first_copy + size){
+ munmap(first_copy, size); // cleanup
+ munmap(second_copy, size);
+ close (seg_fd);
+ perror ("gr_vmcircbuf_mmap_tmpfile: non-contiguous second copy");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+ }
+
+ // cut the tmp file down to size
+ if (ftruncate (seg_fd, (off_t) size) == -1){
+ munmap(first_copy, size); // cleanup
+ munmap(second_copy, size);
+ close (seg_fd);
+ perror ("gr_vmcircbuf_mmap_tmpfile: ftruncate (2)");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+ }
+
+ close (seg_fd); // fd no longer needed. The mapping is retained.
+
+ // Now remember the important stuff
+
+ d_base = (char *) first_copy;
+ d_size = size;
+#endif
+}
+
+gr_vmcircbuf_mmap_tmpfile::~gr_vmcircbuf_mmap_tmpfile ()
+{
+#if defined(HAVE_MMAP)
+ if (munmap (d_base, 2 * d_size) == -1){
+ perror ("gr_vmcircbuf_mmap_tmpfile: munmap (2)");
+ }
+#endif
+}
+
+// ----------------------------------------------------------------
+// The factory interface
+// ----------------------------------------------------------------
+
+
+gr_vmcircbuf_factory *gr_vmcircbuf_mmap_tmpfile_factory::s_the_factory = 0;
+
+gr_vmcircbuf_factory *
+gr_vmcircbuf_mmap_tmpfile_factory::singleton ()
+{
+ if (s_the_factory)
+ return s_the_factory;
+
+ s_the_factory = new gr_vmcircbuf_mmap_tmpfile_factory ();
+ return s_the_factory;
+}
+
+int
+gr_vmcircbuf_mmap_tmpfile_factory::granularity ()
+{
+ return gr_pagesize ();
+}
+
+gr_vmcircbuf *
+gr_vmcircbuf_mmap_tmpfile_factory::make (int size)
+{
+ try {
+ return new gr_vmcircbuf_mmap_tmpfile (size);
+ }
+ catch (...){
+ return 0;
+ }
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.h b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.h
new file mode 100644
index 0000000000..3b9f5dba8a
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.h
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GR_VMCIRCBUF_MMAP_TMPFILE_H_
+#define _GR_VMCIRCBUF_MMAP_TMPFILE_H_
+
+#include <gr_vmcircbuf.h>
+
+/*!
+ * \brief concrete class to implement circular buffers with mmap and shm_open
+ */
+class gr_vmcircbuf_mmap_tmpfile : public gr_vmcircbuf {
+ public:
+
+ // CREATORS
+
+ gr_vmcircbuf_mmap_tmpfile (int size);
+ virtual ~gr_vmcircbuf_mmap_tmpfile ();
+};
+
+/*!
+ * \brief concrete factory for circular buffers built using mmap and shm_open
+ */
+class gr_vmcircbuf_mmap_tmpfile_factory : public gr_vmcircbuf_factory {
+ private:
+ static gr_vmcircbuf_factory *s_the_factory;
+
+ public:
+ static gr_vmcircbuf_factory *singleton ();
+
+ virtual const char *name () const { return "gr_vmcircbuf_mmap_tmpfile_factory"; }
+
+ /*!
+ * \brief return granularity of mapping, typically equal to page size
+ */
+ virtual int granularity ();
+
+ /*!
+ * \brief return a gr_vmcircbuf, or 0 if unable.
+ *
+ * Call this to create a doubly mapped circular buffer.
+ */
+ virtual gr_vmcircbuf *make (int size);
+};
+
+#endif /* _GR_VMCIRCBUF_MMAP_TMPFILE_H_ */
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.cc b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.cc
new file mode 100644
index 0000000000..4b6fcfe338
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.cc
@@ -0,0 +1,192 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_vmcircbuf_sysv_shm.h>
+#include <stdexcept>
+#include <assert.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#ifdef HAVE_SYS_IPC_H
+#include <sys/ipc.h>
+#endif
+#ifdef HAVE_SYS_SHM_H
+#include <sys/shm.h>
+#endif
+#include <errno.h>
+#include <stdio.h>
+#include <gr_pagesize.h>
+
+
+gr_vmcircbuf_sysv_shm::gr_vmcircbuf_sysv_shm (int size)
+ : gr_vmcircbuf (size)
+{
+#if !defined(HAVE_SYS_SHM_H)
+ fprintf (stderr, "gr_vmcircbuf_sysv_shm: sysv shared memory is not available\n");
+ throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+#else
+
+ int pagesize = gr_pagesize();
+
+ if (size <= 0 || (size % pagesize) != 0){
+ fprintf (stderr, "gr_vmcircbuf_sysv_shm: invalid size = %d\n", size);
+ throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+ }
+
+ int shmid_guard = -1;
+ int shmid1 = -1;
+ int shmid2 = -1;
+
+ // We use this as a guard page. We'll map it read-only on both ends of the buffer.
+ // Ideally we'd map it no access, but I don't think that's possible with SysV
+ if ((shmid_guard = shmget (IPC_PRIVATE, pagesize, IPC_CREAT | 0400)) == -1){
+ perror ("gr_vmcircbuf_sysv_shm: shmget (0)");
+ throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+ }
+
+ if ((shmid2 = shmget (IPC_PRIVATE, 2 * size + 2 * pagesize, IPC_CREAT | 0700)) == -1){
+ perror ("gr_vmcircbuf_sysv_shm: shmget (1)");
+ throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+ }
+
+ if ((shmid1 = shmget (IPC_PRIVATE, size, IPC_CREAT | 0700)) == -1){
+ perror ("gr_vmcircbuf_sysv_shm: shmget (2)");
+ shmctl (shmid2, IPC_RMID, 0);
+ throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+ }
+
+ void *first_copy = shmat (shmid2, 0, 0);
+ if (first_copy == (void *) -1){
+ perror ("gr_vmcircbuf_sysv_shm: shmat (1)");
+ shmctl (shmid_guard, IPC_RMID, 0);
+ shmctl (shmid2, IPC_RMID, 0);
+ shmctl (shmid1, IPC_RMID, 0);
+ throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+ }
+
+ shmctl (shmid2, IPC_RMID, 0);
+
+ // There may be a race between our detach and attach.
+ //
+ // If the system allocates all shared memory segments at the same
+ // virtual addresses in all processes and if the system allocates
+ // some other segment to first_copy or first_copoy + size between
+ // our detach and attach, the attaches below could fail [I've never
+ // seen it fail for this reason].
+
+ shmdt (first_copy);
+
+ // first read-only guard page
+ if (shmat (shmid_guard, first_copy, SHM_RDONLY) == (void *) -1){
+ perror ("gr_vmcircbuf_sysv_shm: shmat (2)");
+ shmctl (shmid_guard, IPC_RMID, 0);
+ shmctl (shmid1, IPC_RMID, 0);
+ throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+ }
+
+ // first copy
+ if (shmat (shmid1, (char *) first_copy + pagesize, 0) == (void *) -1){
+ perror ("gr_vmcircbuf_sysv_shm: shmat (3)");
+ shmctl (shmid_guard, IPC_RMID, 0);
+ shmctl (shmid1, IPC_RMID, 0);
+ shmdt (first_copy);
+ throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+ }
+
+ // second copy
+ if (shmat (shmid1, (char *) first_copy + pagesize + size, 0) == (void *) -1){
+ perror ("gr_vmcircbuf_sysv_shm: shmat (4)");
+ shmctl (shmid_guard, IPC_RMID, 0);
+ shmctl (shmid1, IPC_RMID, 0);
+ shmdt ((char *)first_copy + pagesize);
+ throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+ }
+
+ // second read-only guard page
+ if (shmat (shmid_guard, (char *) first_copy + pagesize + 2 * size, SHM_RDONLY) == (void *) -1){
+ perror ("gr_vmcircbuf_sysv_shm: shmat (5)");
+ shmctl (shmid_guard, IPC_RMID, 0);
+ shmctl (shmid1, IPC_RMID, 0);
+ shmdt (first_copy);
+ shmdt ((char *)first_copy + pagesize);
+ shmdt ((char *)first_copy + pagesize + size);
+ throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+ }
+
+ shmctl (shmid1, IPC_RMID, 0);
+ shmctl (shmid_guard, IPC_RMID, 0);
+
+ // Now remember the important stuff
+
+ d_base = (char *) first_copy + pagesize;
+ d_size = size;
+#endif
+}
+
+gr_vmcircbuf_sysv_shm::~gr_vmcircbuf_sysv_shm ()
+{
+#if defined(HAVE_SYS_SHM_H)
+ if (shmdt (d_base - gr_pagesize()) == -1
+ || shmdt (d_base) == -1
+ || shmdt (d_base + d_size) == -1
+ || shmdt (d_base + 2 * d_size) == -1){
+ perror ("gr_vmcircbuf_sysv_shm: shmdt (2)");
+ }
+#endif
+}
+
+// ----------------------------------------------------------------
+// The factory interface
+// ----------------------------------------------------------------
+
+
+gr_vmcircbuf_factory *gr_vmcircbuf_sysv_shm_factory::s_the_factory = 0;
+
+gr_vmcircbuf_factory *
+gr_vmcircbuf_sysv_shm_factory::singleton ()
+{
+ if (s_the_factory)
+ return s_the_factory;
+
+ s_the_factory = new gr_vmcircbuf_sysv_shm_factory ();
+ return s_the_factory;
+}
+
+int
+gr_vmcircbuf_sysv_shm_factory::granularity ()
+{
+ return gr_pagesize ();
+}
+
+gr_vmcircbuf *
+gr_vmcircbuf_sysv_shm_factory::make (int size)
+{
+ try {
+ return new gr_vmcircbuf_sysv_shm (size);
+ }
+ catch (...){
+ return 0;
+ }
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.h b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.h
new file mode 100644
index 0000000000..9a8c128a52
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.h
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GR_VMCIRCBUF_SYSV_SHM_H_
+#define _GR_VMCIRCBUF_SYSV_SHM_H_
+
+#include <gr_vmcircbuf.h>
+
+/*!
+ * \brief concrete class to implement circular buffers with mmap and shm_open
+ */
+class gr_vmcircbuf_sysv_shm : public gr_vmcircbuf {
+ public:
+
+ // CREATORS
+
+ gr_vmcircbuf_sysv_shm (int size);
+ virtual ~gr_vmcircbuf_sysv_shm ();
+};
+
+/*!
+ * \brief concrete factory for circular buffers built using mmap and shm_open
+ */
+class gr_vmcircbuf_sysv_shm_factory : public gr_vmcircbuf_factory {
+ private:
+ static gr_vmcircbuf_factory *s_the_factory;
+
+ public:
+ static gr_vmcircbuf_factory *singleton ();
+
+ virtual const char *name () const { return "gr_vmcircbuf_sysv_shm_factory"; }
+
+ /*!
+ * \brief return granularity of mapping, typically equal to page size
+ */
+ virtual int granularity ();
+
+ /*!
+ * \brief return a gr_vmcircbuf, or 0 if unable.
+ *
+ * Call this to create a doubly mapped circular buffer.
+ */
+ virtual gr_vmcircbuf *make (int size);
+};
+
+#endif /* _GR_VMCIRCBUF_SYSV_SHM_H_ */
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_block.cc b/gnuradio-core/src/lib/runtime/qa_gr_block.cc
new file mode 100644
index 0000000000..e3a21be350
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_block.cc
@@ -0,0 +1,89 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <qa_gr_block.h>
+#include <gr_block.h>
+#include <gr_runtime.h>
+#include <gr_io_signature.h>
+#include <gr_null_sink.h>
+#include <gr_null_source.h>
+
+
+// ----------------------------------------------------------------
+
+
+void
+qa_gr_block::t0 ()
+{
+ // test creation of sources
+ gr_block_sptr src1 (gr_make_null_source (sizeof (int)));
+ CPPUNIT_ASSERT_EQUAL (std::string ("null_source"), src1->name ());
+ CPPUNIT_ASSERT_EQUAL (0, src1->input_signature()->max_streams ());
+ CPPUNIT_ASSERT_EQUAL (1, src1->output_signature()->min_streams ());
+ CPPUNIT_ASSERT_EQUAL (1, src1->output_signature()->max_streams ());
+ CPPUNIT_ASSERT_EQUAL (sizeof (int),
+ src1->output_signature()->sizeof_stream_item (0));
+
+ gr_block_sptr src2 (gr_make_null_source (sizeof (short)));
+ CPPUNIT_ASSERT_EQUAL (std::string ("null_source"), src2->name ());
+ CPPUNIT_ASSERT_EQUAL (0, src2->input_signature()->max_streams ());
+ CPPUNIT_ASSERT_EQUAL (1, src2->output_signature()->min_streams ());
+ CPPUNIT_ASSERT_EQUAL (1, src2->output_signature()->max_streams ());
+ CPPUNIT_ASSERT_EQUAL (sizeof (short),
+ src2->output_signature()->sizeof_stream_item (0));
+}
+
+
+void
+qa_gr_block::t1 ()
+{
+ // test creation of sinks
+ gr_block_sptr dst1 (gr_make_null_sink (sizeof (int)));
+ CPPUNIT_ASSERT_EQUAL (std::string ("null_sink"), dst1->name ());
+ CPPUNIT_ASSERT_EQUAL (1, dst1->input_signature()->min_streams ());
+ CPPUNIT_ASSERT_EQUAL (1, dst1->input_signature()->max_streams ());
+ CPPUNIT_ASSERT_EQUAL (sizeof (int),
+ dst1->input_signature()->sizeof_stream_item (0));
+
+ CPPUNIT_ASSERT_EQUAL (0, dst1->output_signature()->max_streams ());
+
+ gr_block_sptr dst2 (gr_make_null_sink (sizeof (short)));
+ CPPUNIT_ASSERT_EQUAL (std::string ("null_sink"), dst2->name ());
+ CPPUNIT_ASSERT_EQUAL (1, dst2->input_signature()->min_streams ());
+ CPPUNIT_ASSERT_EQUAL (1, dst2->input_signature()->max_streams ());
+ CPPUNIT_ASSERT_EQUAL (sizeof (short),
+ dst2->input_signature()->sizeof_stream_item (0));
+ CPPUNIT_ASSERT_EQUAL (0, dst2->output_signature()->max_streams ());
+}
+
+void
+qa_gr_block::t2 ()
+{
+}
+
+void
+qa_gr_block::t3 ()
+{
+}
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_block.h b/gnuradio-core/src/lib/runtime/qa_gr_block.h
new file mode 100644
index 0000000000..6e30825146
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_QA_GR_BLOCK_H
+#define INCLUDED_QA_GR_BLOCK_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+#include <stdexcept>
+
+class qa_gr_block : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gr_block);
+ CPPUNIT_TEST (t0);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST (t3);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void t0 ();
+ void t1 ();
+ void t2 ();
+ void t3 ();
+
+};
+
+
+#endif /* INCLUDED_QA_GR_BLOCK_H */
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_buffer.cc b/gnuradio-core/src/lib/runtime/qa_gr_buffer.cc
new file mode 100644
index 0000000000..5c549d0b98
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <qa_gr_buffer.h>
+#include <gr_buffer.h>
+#include <cppunit/TestAssert.h>
+#include <stdlib.h>
+#include <gr_random.h>
+
+static void
+leak_check (void f ())
+{
+ long buffer_count = gr_buffer_ncurrently_allocated ();
+ long buffer_reader_count = gr_buffer_reader_ncurrently_allocated ();
+
+ f ();
+
+ CPPUNIT_ASSERT_EQUAL (buffer_reader_count, gr_buffer_reader_ncurrently_allocated ());
+ CPPUNIT_ASSERT_EQUAL (buffer_count, gr_buffer_ncurrently_allocated ());
+}
+
+
+// ----------------------------------------------------------------------------
+// test single writer, no readers...
+//
+
+static void
+t0_body ()
+{
+ int nitems = 4000 / sizeof (int);
+ int counter = 0;
+
+ gr_buffer_sptr buf (gr_make_buffer (nitems, sizeof (int)));
+
+ int last_sa;
+ int sa;
+
+ sa = buf->space_available ();
+ CPPUNIT_ASSERT (sa > 0);
+ last_sa = sa;
+
+ for (int i = 0; i < 5; i++){
+ sa = buf->space_available ();
+ CPPUNIT_ASSERT_EQUAL (last_sa, sa);
+ last_sa = sa;
+
+ int *p = (int *) buf->write_pointer ();
+ CPPUNIT_ASSERT (p != 0);
+
+ for (int j = 0; j < sa; j++)
+ *p++ = counter++;
+
+ buf->update_write_pointer (sa);
+ }
+}
+
+// ----------------------------------------------------------------------------
+// test single writer, single reader
+//
+
+static void
+t1_body ()
+ {
+ int nitems = 4000 / sizeof (int);
+ int write_counter = 0;
+ int read_counter = 0;
+
+ gr_buffer_sptr buf (gr_make_buffer (nitems, sizeof (int)));
+ gr_buffer_reader_sptr r1 (gr_buffer_add_reader (buf, 1));
+
+
+ int sa;
+
+ // write 1/3 of buffer
+
+ sa = buf->space_available ();
+ CPPUNIT_ASSERT (sa > 0);
+
+ int *p = (int *) buf->write_pointer ();
+ CPPUNIT_ASSERT (p != 0);
+
+ for (int j = 0; j < sa/3; j++){
+ *p++ = write_counter++;
+ }
+ buf->update_write_pointer (sa/3);
+
+
+ // write the next 1/3 (1/2 of what's left)
+
+ sa = buf->space_available ();
+ CPPUNIT_ASSERT (sa > 0);
+
+ p = (int *) buf->write_pointer ();
+ CPPUNIT_ASSERT (p != 0);
+
+ for (int j = 0; j < sa/2; j++){
+ *p++ = write_counter++;
+ }
+ buf->update_write_pointer (sa/2);
+
+
+ // check that we can read it OK
+
+ int ia = r1->items_available ();
+ CPPUNIT_ASSERT_EQUAL (write_counter, ia);
+
+ int *rp = (int *) r1->read_pointer ();
+ CPPUNIT_ASSERT (rp != 0);
+
+ for (int i = 0; i < ia/2; i++){
+ CPPUNIT_ASSERT_EQUAL (read_counter, *rp);
+ read_counter++;
+ rp++;
+ }
+ r1->update_read_pointer (ia/2);
+
+ // read the rest
+
+ ia = r1->items_available ();
+ rp = (int *) r1->read_pointer ();
+ CPPUNIT_ASSERT (rp != 0);
+
+ for (int i = 0; i < ia; i++){
+ CPPUNIT_ASSERT_EQUAL (read_counter, *rp);
+ read_counter++;
+ rp++;
+ }
+ r1->update_read_pointer (ia);
+}
+
+// ----------------------------------------------------------------------------
+// single writer, single reader: check wrap-around
+//
+
+static void
+t2_body ()
+{
+ // 64K is the largest granularity we've seen so far (MS windows file mapping).
+ // This allows a bit of "white box testing"
+
+ int nitems = (64 * (1L << 10)) / sizeof (int); // 64K worth of ints
+
+ gr_buffer_sptr buf (gr_make_buffer (nitems, sizeof (int)));
+ gr_buffer_reader_sptr r1 (gr_buffer_add_reader (buf, 1));
+
+ int read_counter = 0;
+ int write_counter = 0;
+ int n;
+ int *wp = 0;
+ int *rp = 0;
+
+ // Write 3/4 of buffer
+
+ n = (int) (buf->space_available () * 0.75);
+ wp = (int *) buf->write_pointer ();
+
+ for (int i = 0; i < n; i++)
+ *wp++ = write_counter++;
+ buf->update_write_pointer (n);
+
+ // Now read it all
+
+ int m = r1->items_available ();
+ CPPUNIT_ASSERT_EQUAL (n, m);
+ rp = (int *) r1->read_pointer ();
+
+ for (int i = 0; i < m; i++){
+ CPPUNIT_ASSERT_EQUAL (read_counter, *rp);
+ read_counter++;
+ rp++;
+ }
+ r1->update_read_pointer (m);
+
+ // Now write as much as we can.
+ // This will wrap around the buffer
+
+ n = buf->space_available ();
+ CPPUNIT_ASSERT_EQUAL (nitems - 1, n); // white box test
+ wp = (int *) buf->write_pointer ();
+
+ for (int i = 0; i < n; i++)
+ *wp++ = write_counter++;
+ buf->update_write_pointer (n);
+
+ // now read it all
+
+ m = r1->items_available ();
+ CPPUNIT_ASSERT_EQUAL (n, m);
+ rp = (int *) r1->read_pointer ();
+
+ for (int i = 0; i < m; i++){
+ CPPUNIT_ASSERT_EQUAL (read_counter, *rp);
+ read_counter++;
+ rp++;
+ }
+ r1->update_read_pointer (m);
+
+}
+
+// ----------------------------------------------------------------------------
+// single writer, N readers, randomized order and lengths
+// ----------------------------------------------------------------------------
+
+static void
+t3_body ()
+{
+ int nitems = (64 * (1L << 10)) / sizeof (int);
+
+ static const int N = 5;
+ gr_buffer_sptr buf (gr_make_buffer (nitems, sizeof (int)));
+ gr_buffer_reader_sptr reader[N];
+ int read_counter[N];
+ int write_counter = 0;
+ gr_random random;
+
+ for (int i = 0; i < N; i++){
+ read_counter[i] = 0;
+ reader[i] = gr_buffer_add_reader (buf, 1);
+ }
+
+ for (int lc = 0; lc < 1000; lc++){
+
+ // write some
+
+ int n = (int) (buf->space_available () * random.ran1 ());
+ int *wp = (int *) buf->write_pointer ();
+
+ for (int i = 0; i < n; i++)
+ *wp++ = write_counter++;
+
+ buf->update_write_pointer (n);
+
+ // pick a random reader and read some
+
+ int r = (int) (N * random.ran1 ());
+ CPPUNIT_ASSERT (0 <= r && r < N);
+
+ int m = reader[r]->items_available ();
+ int *rp = (int *) reader[r]->read_pointer ();
+
+ for (int i = 0; i < m; i++){
+ CPPUNIT_ASSERT_EQUAL (read_counter[r], *rp);
+ read_counter[r]++;
+ rp++;
+ }
+ reader[r]->update_read_pointer (m);
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+
+void
+qa_gr_buffer::t0 ()
+{
+ leak_check (t0_body);
+}
+
+void
+qa_gr_buffer::t1 ()
+{
+ leak_check (t1_body);
+}
+
+void
+qa_gr_buffer::t2 ()
+{
+ leak_check (t2_body);
+}
+
+void
+qa_gr_buffer::t3 ()
+{
+ leak_check (t3_body);
+}
+
+void
+qa_gr_buffer::t4 ()
+{
+}
+
+void
+qa_gr_buffer::t5 ()
+{
+}
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_buffer.h b/gnuradio-core/src/lib/runtime/qa_gr_buffer.h
new file mode 100644
index 0000000000..700629cc4c
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_QA_GR_BUFFER_H
+#define INCLUDED_QA_GR_BUFFER_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_buffer : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gr_buffer);
+ CPPUNIT_TEST (t0);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST (t3);
+ CPPUNIT_TEST (t4);
+ CPPUNIT_TEST (t5);
+ CPPUNIT_TEST_SUITE_END ();
+
+
+ private:
+
+ void t0 ();
+ void t1 ();
+ void t2 ();
+ void t3 ();
+ void t4 ();
+ void t5 ();
+};
+
+
+
+#endif /* INCLUDED_QA_GR_BUFFER_H */
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_io_signature.cc b/gnuradio-core/src/lib/runtime/qa_gr_io_signature.cc
new file mode 100644
index 0000000000..c180e7b742
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_io_signature.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <qa_gr_io_signature.h>
+#include <gr_io_signature.h>
+
+void
+qa_gr_io_signature::t0 ()
+{
+ gr_make_io_signature (1, 1, sizeof (int));
+}
+
+void
+qa_gr_io_signature::t1 ()
+{
+ gr_make_io_signature (3, 1, sizeof (int)); // throws std::invalid_argument
+}
+
+void
+qa_gr_io_signature::t2 ()
+{
+ gr_io_signature_sptr p =
+ gr_make_io_signature (3, gr_io_signature::IO_INFINITE, sizeof (int));
+
+ CPPUNIT_ASSERT_EQUAL (p->min_streams (), 3);
+ CPPUNIT_ASSERT_EQUAL (p->sizeof_stream_item (0), sizeof (int));
+}
+
+void
+qa_gr_io_signature::t3 ()
+{
+}
+
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_io_signature.h b/gnuradio-core/src/lib/runtime/qa_gr_io_signature.h
new file mode 100644
index 0000000000..225ce80687
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_io_signature.h
@@ -0,0 +1,47 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_QA_GR_IO_SIGNATURE_H
+#define INCLUDED_QA_GR_IO_SIGNATURE_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+#include <stdexcept>
+
+class qa_gr_io_signature : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gr_io_signature);
+ CPPUNIT_TEST (t0);
+ CPPUNIT_TEST_EXCEPTION (t1, std::invalid_argument);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST (t3);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void t0 ();
+ void t1 ();
+ void t2 ();
+ void t3 ();
+
+};
+
+#endif /* INCLUDED_QA_GR_IO_SIGNATURE_H */
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_vmcircbuf.cc b/gnuradio-core/src/lib/runtime/qa_gr_vmcircbuf.cc
new file mode 100644
index 0000000000..f3c815a0d5
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qa_gr_vmcircbuf.h>
+#include <cppunit/TestAssert.h>
+#include <gr_vmcircbuf.h>
+#include <stdio.h>
+
+void
+qa_gr_vmcircbuf::test_all ()
+{
+ int verbose = 1; // summary
+
+ bool ok = gr_vmcircbuf_sysconfig::test_all_factories (verbose);
+
+ CPPUNIT_ASSERT_EQUAL (true, ok);
+}
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_vmcircbuf.h b/gnuradio-core/src/lib/runtime/qa_gr_vmcircbuf.h
new file mode 100644
index 0000000000..41f69c3534
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _QA_GR_VMCIRCBUF_H_
+#define _QA_GR_VMCIRCBUF_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_vmcircbuf : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gr_vmcircbuf);
+ CPPUNIT_TEST (test_all);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void test_all ();
+};
+
+
+#endif /* _QA_GR_VMCIRCBUF_H_ */
diff --git a/gnuradio-core/src/lib/runtime/qa_runtime.cc b/gnuradio-core/src/lib/runtime/qa_runtime.cc
new file mode 100644
index 0000000000..668628f2ac
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_runtime.cc
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * This class gathers together all the test cases for the gr
+ * directory into a single test suite. As you create new test cases,
+ * add them here.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <qa_runtime.h>
+#include <qa_gr_vmcircbuf.h>
+#include <qa_gr_io_signature.h>
+#include <qa_gr_block.h>
+#include <qa_gr_buffer.h>
+
+CppUnit::TestSuite *
+qa_runtime::suite ()
+{
+ CppUnit::TestSuite *s = new CppUnit::TestSuite ("runtime");
+
+ s->addTest (qa_gr_vmcircbuf::suite ());
+ s->addTest (qa_gr_io_signature::suite ());
+ s->addTest (qa_gr_block::suite ());
+ s->addTest (qa_gr_buffer::suite ());
+
+ return s;
+}
diff --git a/gnuradio-core/src/lib/runtime/qa_runtime.h b/gnuradio-core/src/lib/runtime/qa_runtime.h
new file mode 100644
index 0000000000..5862b1ea20
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_runtime.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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _QA_RUNTIME_H_
+#define _QA_RUNTIME_H_
+
+#include <cppunit/TestSuite.h>
+
+//! collect all the tests for the runtime directory
+
+class qa_runtime {
+ public:
+ //! return suite of tests for all of runtime directory
+ static CppUnit::TestSuite *suite ();
+};
+
+
+#endif /* _QA_RUNTIME_H_ */
diff --git a/gnuradio-core/src/lib/runtime/runtime.i b/gnuradio-core/src/lib/runtime/runtime.i
new file mode 100644
index 0000000000..d8dd34f1ee
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/runtime.i
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+%{
+#include <gr_runtime.h>
+#include <gr_io_signature.h>
+#include <gr_buffer.h>
+#include <gr_block.h>
+#include <gr_block_detail.h>
+#include <gr_single_threaded_scheduler.h>
+#include <gr_message.h>
+#include <gr_msg_handler.h>
+#include <gr_msg_queue.h>
+#include <gr_dispatcher.h>
+#include <gr_error_handler.h>
+#include <gr_realtime.h>
+%}
+
+%include <gr_io_signature.i>
+%include <gr_buffer.i>
+%include <gr_block.i>
+%include <gr_block_detail.i>
+%include <gr_swig_block_magic.i>
+%include <gr_single_threaded_scheduler.i>
+%include <gr_message.i>
+%include <gr_msg_handler.i>
+%include <gr_msg_queue.i>
+%include <gr_dispatcher.i>
+%include <gr_error_handler.i>
+%include <gr_realtime.i>
diff --git a/gnuradio-core/src/lib/runtime/test_shared_block_ptr.cc b/gnuradio-core/src/lib/runtime/test_shared_block_ptr.cc
new file mode 100644
index 0000000000..26bfa6d2db
--- /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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gr_shared_block_sptr.h>
+#include <gr_vector_source_i.h>
+
+gr_block_sptr
+foo (gr_vector_source_i_sptr s)
+{
+ return gr_block_sptr (s);
+}
+
+typedef gr_shared_block_sptr<gr_vector_source_i> gr_vector_source_i_ptrX;
+//typedef boost::shared_ptr<gr_vector_source_i> gr_vector_source_i_ptrX;
+
+gr_vector_source_i_ptrX
+bar (gr_vector_source_i *s)
+{
+ return gr_vector_source_i_ptrX (s);
+}
+
+gr_block_sptr
+baz_1 (gr_vector_source_i_ptrX s)
+{
+ return gr_block_sptr (s);
+}
+
+#if 0
+gr_block_sptr
+baz_2 (gr_vector_source_i_ptrX s)
+{
+ return s.block_sptr ();
+}
+#endif
diff --git a/gnuradio-core/src/lib/swig/Makefile.am b/gnuradio-core/src/lib/swig/Makefile.am
new file mode 100644
index 0000000000..77bd030836
--- /dev/null
+++ b/gnuradio-core/src/lib/swig/Makefile.am
@@ -0,0 +1,111 @@
+#
+# Copyright 2001,2003,2004,2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+include $(top_srcdir)/Makefile.common
+
+# Install this stuff in the gr subdirectory of the python pkg dir.
+# This usually ends up at:
+# ${prefix}/lib/python${python_version}/site-packages/gnuradio/gr
+
+grgrpythondir = $(grpythondir)/gr
+grgrlibdir = $(grpyexecdir)/gr
+
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) -I$(srcdir)
+
+
+EXTRA_DIST = gen-swig-bug-fix
+
+
+LOCAL_IFILES = \
+ gnuradio.i \
+ shared_ptr.i
+
+ALL_IFILES = \
+ $(LOCAL_IFILES)
+
+
+BUILT_SOURCES = \
+ gnuradio_swig_python.cc \
+ gnuradio_swig_python.py \
+ gnuradio_swig_python.h \
+ gnuradio_swig_bug_workaround.h
+
+grgrpython_PYTHON = \
+ gnuradio_swig_python.py
+
+
+SWIGPYTHONARGS = $(SWIGPYTHONFLAGS) $(INCLUDES)
+
+
+# ----------------------------------------------------------------
+# _gnuradio_swig_python contains all the glue that implements
+# the gnuradio.gr python package
+
+grgrlib_LTLIBRARIES = \
+ _gnuradio_swig_python.la
+
+_gnuradio_swig_python_la_SOURCES = \
+ gnuradio_swig_python.cc
+
+
+_gnuradio_swig_python_la_LIBADD = \
+ $(top_builddir)/gnuradio-core/src/lib/libgnuradio-core.la \
+ $(PYTHON_LDFLAGS) \
+ -lstdc++
+
+_gnuradio_swig_python_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
+
+
+# KLUDGE: Force runtime include of gnuradio_swig_python.d dependency file.
+# This is not guaranteed to be portable, but will probably work.
+# If it works, we have accurate dependencies for our swig stuff, which is good.
+@am__include@ @am__quote@./gnuradio_swig_python.d@am__quote@
+
+gnuradio_swig_python.cc gnuradio_swig_python.py gnuradio_swig_python.h : gnuradio.i
+ if $(SWIG) $(SWIGPYTHONARGS) -MMD -MF gnuradio_swig_python.Td -module gnuradio_swig_python -o gnuradio_swig_python.cc $< ;\
+ then if test $(host_os) = mingw32; \
+ then sed 's,\\\\,/,g' <gnuradio_swig_python.Td >gnuradio_swig_python.d; rm -f gnuradio_swig_python.Td; \
+ else mv -f gnuradio_swig_python.Td gnuradio_swig_python.d; fi \
+ else rm -f gnuradio_swig_python.Td; exit 1; fi
+
+gnuradio_swig_bug_workaround.h : gnuradio_swig_python.cc $(srcdir)/gen-swig-bug-fix
+ $(srcdir)/gen-swig-bug-fix $< $@
+
+
+# ----------------------------------------------------------------
+
+# Don't distribute output of swig
+dist-hook:
+ @for file in $(BUILT_SOURCES); do echo $(RM) $(distdir)/$$file; done
+ @for file in $(BUILT_SOURCES); do $(RM) $(distdir)/$$file; done
+
+
+grinclude_HEADERS = \
+ gnuradio_swig_bug_workaround.h
+
+swiginclude_HEADERS = \
+ $(LOCAL_IFILES)
+
+MOSTLYCLEANFILES = \
+ $(BUILT_SOURCES) *~ *.pyc
+
+DISTCLEANFILES = gnuradio_swig_python.d
diff --git a/gnuradio-core/src/lib/swig/atsc.i b/gnuradio-core/src/lib/swig/atsc.i
new file mode 100644
index 0000000000..4e8bf48f29
--- /dev/null
+++ b/gnuradio-core/src/lib/swig/atsc.i
@@ -0,0 +1,136 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+%{
+#include <atsc_types.h>
+#include <atsc_consts.h>
+#include <GrAtscRandomizer.h>
+#include <GrAtscRSEncoder.h>
+#include <GrAtscInterleaver.h>
+#include <GrAtscTrellisEncoder.h>
+#include <GrAtscFieldSyncMux.h>
+#include <GrAtscSymbolMapper.h>
+#include <GrAtscConvert2xTo20.h>
+#include <GrWeaverModHead.h>
+#include <GrWeaverModTail.h>
+
+%}
+
+// from atsc_types.h
+class plinfo;
+class atsc_mpeg_packet;
+class atsc_mpeg_packet_no_sync;
+class atsc_mpeg_packet_rs_encoded;
+class atsc_data_segment;
+class atsc_soft_data_segment;
+
+%include <atsc_consts.h>
+
+
+// leave out the VrHistoryProc and pretend we're directly derived from VrSigProc
+
+// %template(VrHistoryProc_1) VrHistoryProc<atsc_mpeg_packet,atsc_mpeg_packet_no_sync>;
+
+class GrAtscRandomizer : public VrSigProc
+// class GrAtscRandomizer : public VrHistoryProc<atsc_mpeg_packet, atsc_mpeg_packet_no_sync>
+{
+public:
+ GrAtscRandomizer ();
+ ~GrAtscRandomizer ();
+};
+
+class GrAtscRSEncoder : public VrSigProc
+{
+public:
+ GrAtscRSEncoder ();
+ ~GrAtscRSEncoder ();
+};
+
+class GrAtscInterleaver : public VrSigProc
+{
+public:
+ GrAtscInterleaver ();
+ ~GrAtscInterleaver ();
+};
+
+class GrAtscTrellisEncoder : public VrSigProc
+{
+public:
+ GrAtscTrellisEncoder ();
+ ~GrAtscTrellisEncoder ();
+};
+
+class GrAtscFieldSyncMux : public VrSigProc
+{
+public:
+ GrAtscFieldSyncMux ();
+ ~GrAtscFieldSyncMux ();
+};
+
+template<class oType>
+class GrAtscSymbolMapper : public VrSigProc
+{
+public:
+ GrAtscSymbolMapper ();
+ ~GrAtscSymbolMapper ();
+};
+
+%template(GrAtscSymbolMapperF) GrAtscSymbolMapper<float>;
+
+template<class iType, class oType>
+class GrWeaverModHead : public VrSigProc
+{
+public:
+ GrWeaverModHead (int interp_factor);
+ ~GrWeaverModHead ();
+};
+
+%template(GrWeaverModHeadFF) GrWeaverModHead<float,float>;
+
+template<class iType, class oType>
+class GrWeaverModTail : public VrSigProc {
+public:
+ GrWeaverModTail (float freq, float gain);
+ ~GrWeaverModTail ();
+
+ //! frequency is in Hz
+ void set_freq (float frequency);
+ void set_gain (float g);
+};
+
+%template(GrWeaverModTailFS) GrWeaverModTail<float,short>;
+
+class GrAtscConvert2xTo20 : public VrSigProc
+{
+public:
+ GrAtscConvert2xTo20 ();
+ ~GrAtscConvert2xTo20 ();
+};
+
+
+#if 0 // FIXME
+%template(VrSource_mpeg_packet) VrSource<atsc_mpeg_packet>;
+%template(VrFileSource_mpeg_packet) VrFileSource<atsc_mpeg_packet>;
+
+%template(VrSink_mpeg_packet) VrSink<atsc_mpeg_packet>;
+%template(VrFileSink_mpeg_packet) VrFileSink<atsc_mpeg_packet>;
+#endif
diff --git a/gnuradio-core/src/lib/swig/gen-swig-bug-fix b/gnuradio-core/src/lib/swig/gen-swig-bug-fix
new file mode 100755
index 0000000000..36332cc599
--- /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 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+import sys
+import re
+
+def write_header (f):
+ f.write ('''/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GNURADIO_SWIG_BUG_WORKAROUND_H
+#define INCLUDED_GNURADIO_SWIG_BUG_WORKAROUND_H
+
+/*
+ * This include files works around a bug in SWIG 1.3.21 and 22
+ * where it fails to emit these declarations when doing
+ * %import "gnuradio.i"
+ */
+
+''')
+
+def write_trailer (f):
+ f.write ('''
+#endif /* INCLUDED_GNURADIO_SWIG_BUG_WORKAROUND_H */
+''')
+
+def doit (input, output):
+ re_RULES_BEGIN = re.compile ('RULES \(BEGIN\)')
+ re_RULES_END = re.compile ('RULES \(END\)')
+ re_RETURN = re.compile ('^\s*return')
+ re_NOT_ID = re.compile ('[^a-zA-Z0-9_]')
+ words = {}
+
+ write_header (output)
+ for line in input:
+ if re_RULES_BEGIN.search (line):
+ break
+
+ for line in input:
+ if re_RULES_END.search (line):
+ break
+ if not re_RETURN.match (line):
+ continue
+ line = re_NOT_ID.sub (' ', line)
+ line = re.sub (' +', ' ', line)
+ for w in line.split (' '):
+ words[w] = 1
+
+ for w in ('', 'return', 'void', 'x'):
+ del words[w]
+
+ wl = words.keys()
+ wl.sort ()
+ for w in wl:
+ output.write ('class ' + w + ';\n')
+
+ write_trailer (output)
+
+
+def main ():
+ if len (sys.argv) != 3:
+ sys.stderr.write ("usage: %s gnuradio_swig_python.cc gnuradio_swig_bug_workaround.h\n"
+ % (sys.argv[0],))
+ sys.exit (1)
+ input_filename = sys.argv[1]
+ output_filename = sys.argv[2]
+ input = open (input_filename, "r")
+ output = open (output_filename, "w")
+ doit (input, output)
+
+if __name__ == '__main__':
+ main ()
+
diff --git a/gnuradio-core/src/lib/swig/gnuradio.i b/gnuradio-core/src/lib/swig/gnuradio.i
new file mode 100644
index 0000000000..b8c58538cd
--- /dev/null
+++ b/gnuradio-core/src/lib/swig/gnuradio.i
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+////////////////////////////////////////////////////////////////////////
+// gnuradio.i
+// SWIG interface definition
+////////////////////////////////////////////////////////////////////////
+
+
+#ifndef SWIGIMPORTED
+// we set the module name on the command line (not any more)
+%module(directors="1") gnuradio_swig_python
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// Headers
+
+
+%{
+#include <gr_types.h>
+#include <stddef.h> // size_t
+%}
+
+%feature("autodoc","1");
+
+%include <shared_ptr.i>
+%include <stl.i>
+%include <std_complex.i>
+
+
+typedef std::complex<float> gr_complex;
+typedef std::complex<double> gr_complexd;
+
+
+// instantiate the required template specializations
+
+namespace std {
+ %template() vector<unsigned char>;
+ %template() vector<char>;
+ %template() vector<short>;
+ %template() vector<int>;
+ %template() vector<float>;
+ %template() vector<double>;
+ %template() vector<std::complex<float> >;
+};
+
+////////////////////////////////////////////////////////////////////////
+
+%constant int sizeof_char = sizeof(char);
+%constant int sizeof_short = sizeof(short);
+%constant int sizeof_int = sizeof(int);
+%constant int sizeof_float = sizeof(float);
+%constant int sizeof_double = sizeof(double);
+%constant int sizeof_gr_complex = sizeof(gr_complex);
+
+////////////////////////////////////////////////////////////////////////
+
+%include <runtime.i>
+%include <general.i>
+%include <filter.i>
+%include <io.i>
+
+// %include <atsc.i>
+
+////////////////////////////////////////////////////////////////////////
diff --git a/gnuradio-core/src/lib/swig/shared_ptr.i b/gnuradio-core/src/lib/swig/shared_ptr.i
new file mode 100644
index 0000000000..9663033ae7
--- /dev/null
+++ b/gnuradio-core/src/lib/swig/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