summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt5
-rw-r--r--cmake/Packaging/Fedora-15.cmake4
-rw-r--r--cmake/Packaging/Fedora-16.cmake4
-rw-r--r--cmake/Packaging/Fedora-17.cmake12
-rw-r--r--cmake/Packaging/Ubuntu-10.04.cmake4
-rw-r--r--cmake/Packaging/Ubuntu-10.10.cmake4
-rw-r--r--cmake/Packaging/Ubuntu-11.04.cmake4
-rw-r--r--cmake/Packaging/Ubuntu-11.10.cmake4
-rw-r--r--cmake/Packaging/Ubuntu-12.04.cmake12
-rw-r--r--docs/doxygen/doxyxml/doxyindex.py56
-rw-r--r--docs/doxygen/other/volk_guide.dox2
-rw-r--r--docs/doxygen/swig_doc.py81
-rw-r--r--docs/sphinx/README13
-rw-r--r--docs/sphinx/gnuradio_sphinx.py38
-rw-r--r--docs/sphinx/source/atsc/blks.rst34
-rw-r--r--docs/sphinx/source/audio/index.rst4
-rw-r--r--docs/sphinx/source/digital/blocks.rst32
-rw-r--r--docs/sphinx/source/fft.rst8
-rw-r--r--docs/sphinx/source/gr/coding_blk.rst16
-rw-r--r--docs/sphinx/source/gr/converter_blk.rst58
-rw-r--r--docs/sphinx/source/gr/demodulation_blk.rst2
-rw-r--r--docs/sphinx/source/gr/dft_blk.rst6
-rw-r--r--docs/sphinx/source/gr/filter_blk.rst86
-rw-r--r--docs/sphinx/source/gr/level_blk.rst46
-rw-r--r--docs/sphinx/source/gr/math_blk.rst112
-rw-r--r--docs/sphinx/source/gr/misc_blk.rst18
-rw-r--r--docs/sphinx/source/gr/modulation_blk.rst6
-rw-r--r--docs/sphinx/source/gr/sink_blk.rst44
-rw-r--r--docs/sphinx/source/gr/slicedice_blk.rst22
-rw-r--r--docs/sphinx/source/gr/source_blk.rst44
-rw-r--r--docs/sphinx/source/gr/sync_blk.rst12
-rw-r--r--docs/sphinx/source/index.rst2
-rw-r--r--docs/sphinx/source/noaa.rst6
-rw-r--r--docs/sphinx/source/pager/blks.rst10
-rw-r--r--docs/sphinx/source/qtgui/index.rst8
-rw-r--r--docs/sphinx/source/trellis/blks.rst118
-rw-r--r--docs/sphinx/source/video_sdl.rst4
-rw-r--r--docs/sphinx/source/vocoder/blks.rst32
-rw-r--r--docs/sphinx/source/wavelet.rst6
-rw-r--r--gnuradio-core/CMakeLists.txt3
-rw-r--r--gnuradio-core/src/lib/general/CMakeLists.txt27
-rw-r--r--gnuradio-core/src/lib/general/general.i42
-rw-r--r--gnuradio-core/src/lib/general/general_generated.i12
-rw-r--r--gnuradio-core/src/lib/general/gr_add_ff.cc2
-rw-r--r--gnuradio-core/src/lib/general/gr_additive_scrambler_bb.cc65
-rw-r--r--gnuradio-core/src/lib/general/gr_additive_scrambler_bb.h68
-rw-r--r--gnuradio-core/src/lib/general/gr_additive_scrambler_bb.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_annotator_raw.cc106
-rw-r--r--gnuradio-core/src/lib/general/gr_annotator_raw.h69
-rw-r--r--gnuradio-core/src/lib/general/gr_annotator_raw.i (renamed from gnuradio-core/src/lib/general/gr_map_bb.i)22
-rw-r--r--gnuradio-core/src/lib/general/gr_bytes_to_syms.cc74
-rw-r--r--gnuradio-core/src/lib/general/gr_bytes_to_syms.h61
-rw-r--r--gnuradio-core/src/lib/general/gr_char_to_float.cc2
-rw-r--r--gnuradio-core/src/lib/general/gr_char_to_short.cc2
-rw-r--r--gnuradio-core/src/lib/general/gr_complex_to_xxx.cc12
-rw-r--r--gnuradio-core/src/lib/general/gr_conjugate_cc.cc2
-rw-r--r--gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.cc129
-rw-r--r--gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.h87
-rw-r--r--gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.i60
-rw-r--r--gnuradio-core/src/lib/general/gr_descrambler_bb.cc56
-rw-r--r--gnuradio-core/src/lib/general/gr_descrambler_bb.h60
-rw-r--r--gnuradio-core/src/lib/general/gr_descrambler_bb.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_diff_decoder_bb.cc61
-rw-r--r--gnuradio-core/src/lib/general/gr_diff_decoder_bb.h53
-rw-r--r--gnuradio-core/src/lib/general/gr_diff_encoder_bb.cc62
-rw-r--r--gnuradio-core/src/lib/general/gr_diff_encoder_bb.h54
-rw-r--r--gnuradio-core/src/lib/general/gr_diff_phasor_cc.cc61
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_char.cc2
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_int.cc2
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_short.cc2
-rw-r--r--gnuradio-core/src/lib/general/gr_framer_sink_1.cc190
-rw-r--r--gnuradio-core/src/lib/general/gr_framer_sink_1.h107
-rw-r--r--gnuradio-core/src/lib/general/gr_glfsr_source_b.cc84
-rw-r--r--gnuradio-core/src/lib/general/gr_glfsr_source_b.h66
-rw-r--r--gnuradio-core/src/lib/general/gr_glfsr_source_b.i37
-rw-r--r--gnuradio-core/src/lib/general/gr_glfsr_source_f.cc84
-rw-r--r--gnuradio-core/src/lib/general/gr_glfsr_source_f.h66
-rw-r--r--gnuradio-core/src/lib/general/gr_glfsr_source_f.i37
-rw-r--r--gnuradio-core/src/lib/general/gr_head.h3
-rw-r--r--gnuradio-core/src/lib/general/gr_head.i3
-rw-r--r--gnuradio-core/src/lib/general/gr_int_to_float.cc2
-rw-r--r--gnuradio-core/src/lib/general/gr_keep_m_in_n.cc98
-rw-r--r--gnuradio-core/src/lib/general/gr_keep_m_in_n.h67
-rw-r--r--gnuradio-core/src/lib/general/gr_keep_m_in_n.i (renamed from gnuradio-core/src/lib/general/gr_framer_sink_1.i)24
-rw-r--r--gnuradio-core/src/lib/general/gr_map_bb.cc61
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_cc.cc6
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.cc6
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_const_cc.cc6
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_const_ff.cc6
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_ff.cc2
-rw-r--r--gnuradio-core/src/lib/general/gr_pack_k_bits_bb.cc69
-rw-r--r--gnuradio-core/src/lib/general/gr_pack_k_bits_bb.h (renamed from gnuradio-core/src/lib/general/gr_diff_phasor_cc.h)43
-rw-r--r--gnuradio-core/src/lib/general/gr_pack_k_bits_bb.i (renamed from gnuradio-core/src/lib/general/gr_diff_phasor_cc.i)20
-rw-r--r--gnuradio-core/src/lib/general/gr_packet_sink.cc207
-rw-r--r--gnuradio-core/src/lib/general/gr_packet_sink.h112
-rw-r--r--gnuradio-core/src/lib/general/gr_pn_correlator_cc.cc77
-rw-r--r--gnuradio-core/src/lib/general/gr_pn_correlator_cc.h62
-rw-r--r--gnuradio-core/src/lib/general/gr_pn_correlator_cc.i32
-rw-r--r--gnuradio-core/src/lib/general/gr_probe_density_b.cc68
-rw-r--r--gnuradio-core/src/lib/general/gr_probe_density_b.h73
-rw-r--r--gnuradio-core/src/lib/general/gr_scrambler_bb.cc56
-rw-r--r--gnuradio-core/src/lib/general/gr_scrambler_bb.h60
-rw-r--r--gnuradio-core/src/lib/general/gr_scrambler_bb.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_short_to_char.cc2
-rw-r--r--gnuradio-core/src/lib/general/gr_short_to_float.cc2
-rw-r--r--gnuradio-core/src/lib/general/gr_simple_framer.cc101
-rw-r--r--gnuradio-core/src/lib/general/gr_simple_framer.h59
-rw-r--r--gnuradio-core/src/lib/general/gr_simple_framer.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_tag_debug.cc100
-rw-r--r--gnuradio-core/src/lib/general/gr_tag_debug.h85
-rw-r--r--gnuradio-core/src/lib/general/gr_tag_debug.i (renamed from gnuradio-core/src/lib/general/gr_probe_density_b.i)19
-rw-r--r--gnuradio-core/src/lib/general/gr_vector_map.cc117
-rw-r--r--gnuradio-core/src/lib/general/gr_vector_map.h83
-rw-r--r--gnuradio-core/src/lib/general/gr_vector_map.i (renamed from gnuradio-core/src/lib/general/gr_bytes_to_syms.i)12
-rw-r--r--gnuradio-core/src/lib/general/gri_glfsr.cc67
-rw-r--r--gnuradio-core/src/lib/general/qa_general.cc2
-rw-r--r--gnuradio-core/src/lib/general/qa_gri_lfsr.cc142
-rw-r--r--gnuradio-core/src/lib/gengen/CMakeLists.txt4
-rwxr-xr-xgnuradio-core/src/lib/gengen/generate_common.py1
-rw-r--r--gnuradio-core/src/lib/gengen/gr_chunks_to_symbols_XX.cc.t74
-rw-r--r--gnuradio-core/src/lib/gengen/gr_chunks_to_symbols_XX.h.t73
-rw-r--r--gnuradio-core/src/lib/gengen/gr_sig_source_X.cc.t7
-rw-r--r--gnuradio-core/src/lib/gengen/gr_vector_insert_X.cc.t100
-rw-r--r--gnuradio-core/src/lib/gengen/gr_vector_insert_X.h.t61
-rw-r--r--gnuradio-core/src/lib/gengen/gr_vector_insert_X.i.t (renamed from gnuradio-core/src/lib/gengen/gr_chunks_to_symbols_XX.i.t)28
-rw-r--r--gnuradio-core/src/lib/gengen/gr_vector_source_X.h.t3
-rw-r--r--gnuradio-core/src/lib/gengen/gr_vector_source_X.i.t5
-rw-r--r--gnuradio-core/src/lib/io/gri_wavfile.cc120
-rw-r--r--gnuradio-core/src/lib/io/gri_wavfile.h27
-rw-r--r--gnuradio-core/src/lib/runtime/gr_top_block.i2
-rw-r--r--gnuradio-core/src/python/build_utils.py34
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_diff_encoder.py86
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_fsk_stuff.py75
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_glfsr_source.py94
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_keep_m_in_n.py58
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_pack_k_bits.py67
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_scrambler.py64
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_tag_debug.py (renamed from gnuradio-core/src/python/gnuradio/gr/qa_pn_correlator_cc.py)29
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_vector_insert.py (renamed from gnuradio-core/src/python/gnuradio/gr/qa_diff_phasor_cc.py)46
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/qa_vector_map.py105
-rwxr-xr-xgr-audio/examples/python/noise.py3
-rw-r--r--gr-audio/lib/CMakeLists.txt2
-rwxr-xr-xgr-digital/examples/narrowband/digital_bert_rx.py4
-rwxr-xr-xgr-digital/examples/narrowband/digital_bert_tx.py2
-rw-r--r--gr-digital/grc/digital_dxpsk_demod.xml13
-rw-r--r--gr-digital/grc/digital_dxpsk_mod.xml18
-rw-r--r--gr-digital/grc/digital_mpsk_receiver_cc.xml13
-rw-r--r--gr-digital/grc/digital_ofdm_insert_preamble.xml6
-rw-r--r--gr-digital/grc/digital_psk_demod.xml4
-rw-r--r--gr-digital/grc/digital_qam_demod.xml2
-rw-r--r--gr-digital/grc/digital_simple_framer.xml4
-rw-r--r--gr-digital/include/digital_bytes_to_syms.h4
-rw-r--r--gr-digital/include/digital_chunks_to_symbols_XX.h.t2
-rw-r--r--gr-digital/include/digital_framer_sink_1.h2
-rw-r--r--gr-digital/include/digital_glfsr_source_b.h4
-rw-r--r--gr-digital/include/digital_glfsr_source_f.h4
-rw-r--r--gr-digital/include/digital_ofdm_insert_preamble.h4
-rw-r--r--gr-digital/include/digital_pn_correlator_cc.h4
-rw-r--r--gr-digital/lib/digital_constellation.cc4
-rw-r--r--gr-digital/lib/digital_glfsr_source_b.cc6
-rw-r--r--gr-digital/lib/digital_glfsr_source_f.cc6
-rw-r--r--gr-digital/lib/digital_ofdm_insert_preamble.cc33
-rw-r--r--gr-digital/lib/digital_pn_correlator_cc.cc4
-rw-r--r--gr-digital/python/bpsk.py61
-rw-r--r--gr-digital/python/cpm.py2
-rw-r--r--gr-digital/python/generic_mod_demod.py37
-rw-r--r--gr-digital/python/pkt.py2
-rw-r--r--gr-digital/python/psk.py29
-rwxr-xr-xgr-digital/python/qa_constellation.py30
-rwxr-xr-xgr-digital/python/qa_constellation_receiver.py36
-rwxr-xr-xgr-digital/python/qa_glfsr_source.py8
-rw-r--r--gr-digital/python/qam.py14
-rw-r--r--gr-digital/python/qpsk.py91
-rw-r--r--gr-digital/swig/digital_ofdm_insert_preamble.i2
-rw-r--r--gr-fcd/grc/fcd_source_c.xml2
-rw-r--r--gr-fft/include/fft/fft.h6
-rw-r--r--gr-fft/lib/CMakeLists.txt11
-rw-r--r--gr-fft/swig/CMakeLists.txt2
-rw-r--r--gr-filter/CMakeLists.txt113
-rw-r--r--gr-filter/doc/CMakeLists.txt23
-rw-r--r--gr-filter/doc/README.filter13
-rw-r--r--gr-filter/doc/filter.dox27
-rw-r--r--gr-filter/examples/CMakeLists.txt39
-rwxr-xr-xgr-filter/examples/channelize.py195
-rwxr-xr-xgr-filter/examples/chirp_channelize.py205
-rwxr-xr-xgr-filter/examples/decimate.py181
-rwxr-xr-xgr-filter/examples/fft_filter_ccc.py98
-rwxr-xr-xgr-filter/examples/fir_filter_ccc.py92
-rwxr-xr-xgr-filter/examples/fir_filter_fff.py92
-rwxr-xr-xgr-filter/examples/fmtest.py226
-rwxr-xr-xgr-filter/examples/interpolate.py240
-rwxr-xr-xgr-filter/examples/reconstruction.py164
-rwxr-xr-xgr-filter/examples/resampler.py128
-rw-r--r--gr-filter/examples/resampler_demo.grc630
-rwxr-xr-xgr-filter/examples/synth_filter.py85
-rwxr-xr-xgr-filter/examples/synth_to_chan.py118
-rw-r--r--gr-filter/gnuradio-filter.pc.in11
-rw-r--r--gr-filter/grc/CMakeLists.txt41
-rw-r--r--gr-filter/grc/channel_model.xml61
-rw-r--r--gr-filter/grc/dc_blocker_xx.xml51
-rw-r--r--gr-filter/grc/fft_filter_xxx.xml59
-rw-r--r--gr-filter/grc/filter_block_tree.xml51
-rw-r--r--gr-filter/grc/filter_delay_fc.xml31
-rw-r--r--gr-filter/grc/fir_filter_xxx.xml80
-rw-r--r--gr-filter/grc/fractional_interpolator_xx.xml46
-rw-r--r--gr-filter/grc/freq_xlating_fir_filter_xxx.xml93
-rw-r--r--gr-filter/grc/hilbert_fc.xml (renamed from grc/blocks/gr_diff_decoder_bb.xml)19
-rw-r--r--gr-filter/grc/iir_filter_ffd.xml31
-rw-r--r--gr-filter/grc/interp_fir_filter_xxx.xml80
-rw-r--r--gr-filter/grc/pfb_arb_resampler.xml61
-rw-r--r--gr-filter/grc/pfb_channelizer.xml62
-rw-r--r--gr-filter/grc/pfb_decimator.xml43
-rw-r--r--gr-filter/grc/pfb_interpolator.xml36
-rw-r--r--gr-filter/grc/pfb_synthesizer.xml57
-rw-r--r--gr-filter/grc/rational_resampler_base_xxx.xml86
-rw-r--r--gr-filter/grc/single_pole_iir_filter_xx.xml51
-rw-r--r--gr-filter/include/filter/CMakeLists.txt116
-rw-r--r--gr-filter/include/filter/adaptive_fir_ccc.h85
-rw-r--r--gr-filter/include/filter/adaptive_fir_ccf.h81
-rw-r--r--gr-filter/include/filter/api.h (renamed from gnuradio-core/src/lib/general/gr_diff_encoder_bb.i)20
-rw-r--r--gr-filter/include/filter/channel_model.h87
-rw-r--r--gr-filter/include/filter/dc_blocker_cc.h76
-rw-r--r--gr-filter/include/filter/dc_blocker_ff.h76
-rw-r--r--gr-filter/include/filter/fft_filter.h171
-rw-r--r--gr-filter/include/filter/fft_filter_ccc.h86
-rw-r--r--gr-filter/include/filter/fft_filter_fff.h86
-rw-r--r--gr-filter/include/filter/filter_delay_fc.h65
-rw-r--r--gr-filter/include/filter/fir_filter.h222
-rw-r--r--gr-filter/include/filter/fir_filter_XXX.h.t82
-rw-r--r--gr-filter/include/filter/fir_filter_with_buffer.h326
-rw-r--r--gr-filter/include/filter/firdes.h378
-rw-r--r--gr-filter/include/filter/fractional_interpolator_cc.h60
-rw-r--r--gr-filter/include/filter/fractional_interpolator_ff.h60
-rw-r--r--gr-filter/include/filter/freq_xlating_fir_filter_XXX.h.t90
-rw-r--r--gr-filter/include/filter/hilbert_fc.h (renamed from gnuradio-core/src/lib/general/gr_map_bb.h)61
-rw-r--r--gr-filter/include/filter/iir_filter.h183
-rw-r--r--gr-filter/include/filter/iir_filter_ffd.h82
-rw-r--r--gr-filter/include/filter/interp_fir_filter_XXX.h.t81
-rw-r--r--gr-filter/include/filter/interpolator_taps.h140
-rw-r--r--gr-filter/include/filter/mmse_fir_interpolator_cc.h79
-rw-r--r--gr-filter/include/filter/mmse_fir_interpolator_ff.h76
-rw-r--r--gr-filter/include/filter/pfb_arb_resampler_ccf.h151
-rw-r--r--gr-filter/include/filter/pfb_arb_resampler_fff.h152
-rw-r--r--gr-filter/include/filter/pfb_channelizer_ccf.h204
-rw-r--r--gr-filter/include/filter/pfb_decimator_ccf.h131
-rw-r--r--gr-filter/include/filter/pfb_interpolator_ccf.h118
-rw-r--r--gr-filter/include/filter/pfb_synthesizer_ccf.h107
-rw-r--r--gr-filter/include/filter/pm_remez.h72
-rw-r--r--gr-filter/include/filter/polyphase_filterbank.h148
-rw-r--r--gr-filter/include/filter/rational_resampler_base_XXX.h.t61
-rw-r--r--gr-filter/include/filter/single_pole_iir.h200
-rw-r--r--gr-filter/include/filter/single_pole_iir_filter_cc.h78
-rw-r--r--gr-filter/include/filter/single_pole_iir_filter_ff.h78
-rw-r--r--gr-filter/lib/CMakeLists.txt178
-rw-r--r--gr-filter/lib/adaptive_fir_ccc_impl.cc106
-rw-r--r--gr-filter/lib/adaptive_fir_ccc_impl.h61
-rw-r--r--gr-filter/lib/adaptive_fir_ccf_impl.cc106
-rw-r--r--gr-filter/lib/adaptive_fir_ccf_impl.h61
-rw-r--r--gr-filter/lib/channel_model_impl.cc135
-rw-r--r--gr-filter/lib/channel_model_impl.h74
-rw-r--r--gr-filter/lib/dc_blocker_cc_impl.cc144
-rw-r--r--gr-filter/lib/dc_blocker_cc_impl.h76
-rw-r--r--gr-filter/lib/dc_blocker_ff_impl.cc142
-rw-r--r--gr-filter/lib/dc_blocker_ff_impl.h76
-rw-r--r--gr-filter/lib/fft_filter.cc316
-rw-r--r--gr-filter/lib/fft_filter_ccc_impl.cc118
-rw-r--r--gr-filter/lib/fft_filter_ccc_impl.h61
-rw-r--r--gr-filter/lib/fft_filter_fff_impl.cc119
-rw-r--r--gr-filter/lib/fft_filter_fff_impl.h61
-rw-r--r--gr-filter/lib/filter_delay_fc_impl.cc112
-rw-r--r--gr-filter/lib/filter_delay_fc_impl.h56
-rw-r--r--gr-filter/lib/fir_filter.cc667
-rw-r--r--gr-filter/lib/fir_filter_XXX_impl.cc.t104
-rw-r--r--gr-filter/lib/fir_filter_XXX_impl.h.t (renamed from gnuradio-core/src/lib/general/gri_glfsr.h)55
-rw-r--r--gr-filter/lib/fir_filter_with_buffer.cc496
-rw-r--r--gr-filter/lib/firdes.cc855
-rw-r--r--gr-filter/lib/fractional_interpolator_cc_impl.cc125
-rw-r--r--gr-filter/lib/fractional_interpolator_cc_impl.h61
-rw-r--r--gr-filter/lib/fractional_interpolator_ff_impl.cc125
-rw-r--r--gr-filter/lib/fractional_interpolator_ff_impl.h61
-rw-r--r--gr-filter/lib/freq_xlating_fir_filter_XXX_impl.cc.t143
-rw-r--r--gr-filter/lib/freq_xlating_fir_filter_XXX_impl.h.t71
-rw-r--r--gr-filter/lib/hilbert_fc_impl.cc76
-rw-r--r--gr-filter/lib/hilbert_fc_impl.h52
-rw-r--r--gr-filter/lib/iir_filter_ffd_impl.cc85
-rw-r--r--gr-filter/lib/iir_filter_ffd_impl.h56
-rw-r--r--gr-filter/lib/interp_fir_filter_XXX_impl.cc.t151
-rw-r--r--gr-filter/lib/interp_fir_filter_XXX_impl.h.t62
-rw-r--r--gr-filter/lib/mmse_fir_interpolator_cc.cc77
-rw-r--r--gr-filter/lib/mmse_fir_interpolator_ff.cc77
-rw-r--r--gr-filter/lib/pfb_arb_resampler_ccf_impl.cc258
-rw-r--r--gr-filter/lib/pfb_arb_resampler_ccf_impl.h89
-rw-r--r--gr-filter/lib/pfb_arb_resampler_fff_impl.cc258
-rw-r--r--gr-filter/lib/pfb_arb_resampler_fff_impl.h88
-rw-r--r--gr-filter/lib/pfb_channelizer_ccf_impl.cc192
-rw-r--r--gr-filter/lib/pfb_channelizer_ccf_impl.h69
-rw-r--r--gr-filter/lib/pfb_decimator_ccf_impl.cc137
-rw-r--r--gr-filter/lib/pfb_decimator_ccf_impl.h65
-rw-r--r--gr-filter/lib/pfb_interpolator_ccf_impl.cc107
-rw-r--r--gr-filter/lib/pfb_interpolator_ccf_impl.h61
-rw-r--r--gr-filter/lib/pfb_synthesizer_ccf_impl.cc288
-rw-r--r--gr-filter/lib/pfb_synthesizer_ccf_impl.h85
-rw-r--r--gr-filter/lib/pm_remez.cc834
-rw-r--r--gr-filter/lib/polyphase_filterbank.cc114
-rw-r--r--gr-filter/lib/qa_filter.cc47
-rw-r--r--gr-filter/lib/qa_filter.h38
-rw-r--r--gr-filter/lib/qa_fir_filter_with_buffer.cc406
-rw-r--r--gr-filter/lib/qa_fir_filter_with_buffer.h94
-rw-r--r--gr-filter/lib/qa_firdes.cc621
-rw-r--r--gr-filter/lib/qa_firdes.h (renamed from gnuradio-core/src/lib/general/gr_diff_decoder_bb.i)41
-rw-r--r--gr-filter/lib/qa_mmse_fir_interpolator_cc.cc126
-rw-r--r--gr-filter/lib/qa_mmse_fir_interpolator_cc.h48
-rw-r--r--gr-filter/lib/qa_mmse_fir_interpolator_ff.cc71
-rw-r--r--gr-filter/lib/qa_mmse_fir_interpolator_ff.h (renamed from gnuradio-core/src/lib/general/qa_gri_lfsr.h)33
-rw-r--r--gr-filter/lib/rational_resampler_base_XXX_impl.cc.t174
-rw-r--r--gr-filter/lib/rational_resampler_base_XXX_impl.h.t72
-rw-r--r--gr-filter/lib/single_pole_iir_filter_cc_impl.cc89
-rw-r--r--gr-filter/lib/single_pole_iir_filter_cc_impl.h55
-rw-r--r--gr-filter/lib/single_pole_iir_filter_ff_impl.cc87
-rw-r--r--gr-filter/lib/single_pole_iir_filter_ff_impl.h54
-rw-r--r--gr-filter/lib/test_gr_filter.cc (renamed from gnuradio-core/src/lib/general/gr_packet_sink.i)34
-rw-r--r--gr-filter/python/CMakeLists.txt50
-rw-r--r--gr-filter/python/__init__.py30
-rw-r--r--gr-filter/python/optfir.py339
-rw-r--r--gr-filter/python/pfb.py271
-rwxr-xr-xgr-filter/python/qa_adaptive_fir_filter.py159
-rwxr-xr-xgr-filter/python/qa_channel_model.py60
-rwxr-xr-xgr-filter/python/qa_dc_blocker.py109
-rwxr-xr-xgr-filter/python/qa_fft_filter.py380
-rwxr-xr-xgr-filter/python/qa_filter_delay_fc.py318
-rwxr-xr-xgr-filter/python/qa_fir_filter.py318
-rwxr-xr-xgr-filter/python/qa_firdes.py202
-rwxr-xr-xgr-filter/python/qa_fractional_interpolator.py89
-rwxr-xr-xgr-filter/python/qa_freq_xlating_fir_filter.py445
-rwxr-xr-xgr-filter/python/qa_hilbert.py117
-rwxr-xr-xgr-filter/python/qa_iir_filter.py157
-rwxr-xr-xgr-filter/python/qa_interp_fir_filter.py60
-rwxr-xr-xgr-filter/python/qa_pfb_arb_resampler.py95
-rwxr-xr-xgr-filter/python/qa_pfb_channelizer.py104
-rwxr-xr-xgr-filter/python/qa_pfb_decimator.py125
-rwxr-xr-xgr-filter/python/qa_pfb_interpolator.py71
-rwxr-xr-xgr-filter/python/qa_pfb_synthesizer.py87
-rwxr-xr-xgr-filter/python/qa_pm_remez.py188
-rwxr-xr-xgr-filter/python/qa_rational_resampler.py257
-rwxr-xr-xgr-filter/python/qa_single_pole_iir.py114
-rw-r--r--gr-filter/python/rational_resampler.py129
-rw-r--r--gr-filter/swig/CMakeLists.txt53
-rw-r--r--gr-filter/swig/filter_swig.i169
-rwxr-xr-xgr-pager/apps/usrp_flex_all4
-rw-r--r--gr-trellis/doc/gr-trellis.xml4
-rw-r--r--gr-trellis/doc/test_tcm.py2
-rw-r--r--gr-trellis/doc/test_tcm.py.xml2
-rwxr-xr-xgr-trellis/doc/test_viterbi_equalization1.py2
-rw-r--r--gr-trellis/doc/test_viterbi_equalization1.py.xml2
-rwxr-xr-xgr-trellis/src/examples/python/test_cpm.py6
-rwxr-xr-xgr-trellis/src/examples/python/test_pccc_turbo1.py2
-rwxr-xr-xgr-trellis/src/examples/python/test_sccc_hard.py2
-rwxr-xr-xgr-trellis/src/examples/python/test_sccc_soft.py2
-rwxr-xr-xgr-trellis/src/examples/python/test_sccc_turbo.py2
-rwxr-xr-xgr-trellis/src/examples/python/test_sccc_turbo1.py2
-rwxr-xr-xgr-trellis/src/examples/python/test_sccc_turbo2.py2
-rwxr-xr-xgr-trellis/src/examples/python/test_tcm.py2
-rwxr-xr-xgr-trellis/src/examples/python/test_tcm_bit.py2
-rwxr-xr-xgr-trellis/src/examples/python/test_tcm_combined.py2
-rwxr-xr-xgr-trellis/src/examples/python/test_tcm_parallel.py2
-rwxr-xr-xgr-trellis/src/examples/python/test_turbo_equalization.py2
-rwxr-xr-xgr-trellis/src/examples/python/test_turbo_equalization1.py2
-rwxr-xr-xgr-trellis/src/examples/python/test_turbo_equalization2.py2
-rwxr-xr-xgr-trellis/src/examples/python/test_viterbi_equalization.py2
-rwxr-xr-xgr-trellis/src/examples/python/test_viterbi_equalization1.py2
-rwxr-xr-xgr-trellis/src/python/qa_trellis.py2
-rw-r--r--gr-uhd/gnuradio-uhd.pc.in2
-rw-r--r--gr-wavelet/lib/CMakeLists.txt10
-rw-r--r--gr-wavelet/python/CMakeLists.txt4
-rw-r--r--gr-wavelet/swig/CMakeLists.txt2
-rw-r--r--gr-wxgui/CMakeLists.txt2
-rw-r--r--gr-wxgui/grc/wxgui_fftsink2.xml12
-rw-r--r--gr-wxgui/grc/wxgui_waterfallsink2.xml12
-rw-r--r--gr-wxgui/src/python/fft_window.py2
-rw-r--r--gr-wxgui/src/python/fftsink_gl.py3
-rw-r--r--gr-wxgui/src/python/plotter/channel_plotter.py8
-rw-r--r--gr-wxgui/src/python/plotter/common.py1
-rw-r--r--gr-wxgui/src/python/plotter/grid_plotter_base.py14
-rw-r--r--gr-wxgui/src/python/plotter/plotter_base.py5
-rw-r--r--gr-wxgui/src/python/plotter/waterfall_plotter.py8
-rw-r--r--gr-wxgui/src/python/waterfall_window.py3
-rw-r--r--gr-wxgui/src/python/waterfallsink_gl.py3
-rw-r--r--grc/CMakeLists.txt2
-rw-r--r--grc/blocks/block_tree.xml21
-rw-r--r--grc/blocks/gr_additive_scrambler_bb.xml44
-rw-r--r--grc/blocks/gr_chunks_to_symbols.xml77
-rw-r--r--grc/blocks/gr_descrambler_bb.xml38
-rw-r--r--grc/blocks/gr_diff_phasor_cc.xml20
-rw-r--r--grc/blocks/gr_glfsr_source_x.xml59
-rw-r--r--grc/blocks/gr_keep_m_in_n.xml76
-rw-r--r--grc/blocks/gr_map_bb.xml25
-rw-r--r--grc/blocks/gr_pack_k_bits_bb.xml (renamed from grc/blocks/gr_diff_encoder_bb.xml)17
-rw-r--r--grc/blocks/gr_pn_correlator_cc.xml35
-rw-r--r--grc/blocks/gr_probe_density_b.xml34
-rw-r--r--grc/blocks/gr_scrambler_bb.xml38
-rw-r--r--grc/blocks/gr_simple_framer.xml25
-rw-r--r--grc/blocks/gr_tag_debug.xml82
-rw-r--r--grc/blocks/gr_vector_insert_x.xml80
-rw-r--r--grc/grc_gnuradio/blks2/packet.py4
-rw-r--r--grc/python/Port.py4
-rw-r--r--gruel/src/include/gruel/CMakeLists.txt20
-rw-r--r--gruel/src/include/gruel/inet.h.in100
-rw-r--r--gruel/src/lib/pmt/pmt-serial-tags.scm2
-rw-r--r--gruel/src/lib/pmt/pmt_serialize.cc56
-rw-r--r--gruel/src/swig/CMakeLists.txt4
-rw-r--r--volk/apps/volk_profile.cc3
-rw-r--r--volk/gen/archs.xml1
-rw-r--r--volk/include/volk/volk_16i_32fc_dot_prod_32fc_a.h122
-rw-r--r--volk/include/volk/volk_32f_x2_dot_prod_16i_a.h98
-rw-r--r--volk/include/volk/volk_32f_x2_dot_prod_32f_a.h169
-rw-r--r--volk/include/volk/volk_32f_x2_dot_prod_32f_u.h189
-rw-r--r--volk/include/volk/volk_32fc_32f_dot_prod_32fc_a.h111
-rw-r--r--volk/include/volk/volk_32fc_s32fc_x2_rotator_32fc_a.h4
-rw-r--r--volk/include/volk/volk_32fc_x2_dot_prod_32fc_a.h33
-rw-r--r--volk/lib/testqa.cc7
420 files changed, 25925 insertions, 5170 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1a0190bdaa..3a5eb0555e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -107,6 +107,8 @@ set(GR_PKG_CONF_DIR ${GR_CONF_DIR}/${CMAKE_PROJECT_NAME}/conf.d)
set(GR_LIBEXEC_DIR libexec)
set(GR_PKG_LIBEXEC_DIR ${GR_LIBEXEC_DIR}/${CMAKE_PROJECT_NAME})
set(GRC_BLOCKS_DIR ${GR_PKG_DATA_DIR}/grc/blocks)
+set(SYSCONFDIR "${CMAKE_INSTALL_PREFIX}/${GR_CONF_DIR}" CACHE PATH "System configuration directory")
+set(GR_PREFSDIR ${SYSCONFDIR}/${CMAKE_PROJECT_NAME}/conf.d)
########################################################################
# Variables replaced when configuring the package config files
@@ -115,6 +117,8 @@ file(TO_NATIVE_PATH "${CMAKE_INSTALL_PREFIX}" prefix)
file(TO_NATIVE_PATH "\${prefix}" exec_prefix)
file(TO_NATIVE_PATH "\${exec_prefix}/${GR_LIBRARY_DIR}" libdir)
file(TO_NATIVE_PATH "\${prefix}/${GR_INCLUDE_DIR}" includedir)
+file(TO_NATIVE_PATH "${SYSCONFDIR}" SYSCONFDIR)
+file(TO_NATIVE_PATH "${GR_PREFSDIR}" GR_PREFSDIR)
########################################################################
# Create uninstall target
@@ -229,6 +233,7 @@ add_subdirectory(gnuradio-core)
add_subdirectory(grc)
add_subdirectory(gr-fft)
+add_subdirectory(gr-filter)
add_subdirectory(gr-atsc)
add_subdirectory(gr-audio)
add_subdirectory(gr-comedi)
diff --git a/cmake/Packaging/Fedora-15.cmake b/cmake/Packaging/Fedora-15.cmake
index 278d68990a..2e9e78ee11 100644
--- a/cmake/Packaging/Fedora-15.cmake
+++ b/cmake/Packaging/Fedora-15.cmake
@@ -1,6 +1,6 @@
SET(PACKAGE_DEPENDS_GRUEL_RUNTIME "boost-python" "glibc")
SET(PACKAGE_DEPENDS_GRUEL_PYTHON "python")
-SET(PACKAGE_DEPENDS_CORE_RUNTIME "fftw-libs" "gsl")
+SET(PACKAGE_DEPENDS_CORE_RUNTIME "fftw-libs")
SET(PACKAGE_DEPENDS_QTGUI_RUNTIME "qt" "qwt")
SET(PACKAGE_DEPENDS_QTGUI_PYTHON "PyQt4" "PyQwt")
SET(PACKAGE_DEPENDS_GRC "python" "numpy" "gtk2" "python-lxml" "python-cheetah")
@@ -8,3 +8,5 @@ SET(PACKAGE_DEPENDS_WXGUI "wxGTK" "python" "numpy")
SET(PACKAGE_DEPENDS_VIDEO_SDL_RUNTIME "SDL")
SET(PACKAGE_DEPENDS_UHD_RUNTIME "uhd")
SET(PACKAGE_DEPENDS_AUDIO_RUNTIME "pulseaudio" "alsa-lib" "jack-audio-connection-kit")
+SET(PACKAGE_DEPENDS_WAVELET_RUNTIME "gsl")
+SET(PACKAGE_DEPENDS_WAVELET_PYTHON "python" "numpy")
diff --git a/cmake/Packaging/Fedora-16.cmake b/cmake/Packaging/Fedora-16.cmake
index 278d68990a..2e9e78ee11 100644
--- a/cmake/Packaging/Fedora-16.cmake
+++ b/cmake/Packaging/Fedora-16.cmake
@@ -1,6 +1,6 @@
SET(PACKAGE_DEPENDS_GRUEL_RUNTIME "boost-python" "glibc")
SET(PACKAGE_DEPENDS_GRUEL_PYTHON "python")
-SET(PACKAGE_DEPENDS_CORE_RUNTIME "fftw-libs" "gsl")
+SET(PACKAGE_DEPENDS_CORE_RUNTIME "fftw-libs")
SET(PACKAGE_DEPENDS_QTGUI_RUNTIME "qt" "qwt")
SET(PACKAGE_DEPENDS_QTGUI_PYTHON "PyQt4" "PyQwt")
SET(PACKAGE_DEPENDS_GRC "python" "numpy" "gtk2" "python-lxml" "python-cheetah")
@@ -8,3 +8,5 @@ SET(PACKAGE_DEPENDS_WXGUI "wxGTK" "python" "numpy")
SET(PACKAGE_DEPENDS_VIDEO_SDL_RUNTIME "SDL")
SET(PACKAGE_DEPENDS_UHD_RUNTIME "uhd")
SET(PACKAGE_DEPENDS_AUDIO_RUNTIME "pulseaudio" "alsa-lib" "jack-audio-connection-kit")
+SET(PACKAGE_DEPENDS_WAVELET_RUNTIME "gsl")
+SET(PACKAGE_DEPENDS_WAVELET_PYTHON "python" "numpy")
diff --git a/cmake/Packaging/Fedora-17.cmake b/cmake/Packaging/Fedora-17.cmake
new file mode 100644
index 0000000000..2e9e78ee11
--- /dev/null
+++ b/cmake/Packaging/Fedora-17.cmake
@@ -0,0 +1,12 @@
+SET(PACKAGE_DEPENDS_GRUEL_RUNTIME "boost-python" "glibc")
+SET(PACKAGE_DEPENDS_GRUEL_PYTHON "python")
+SET(PACKAGE_DEPENDS_CORE_RUNTIME "fftw-libs")
+SET(PACKAGE_DEPENDS_QTGUI_RUNTIME "qt" "qwt")
+SET(PACKAGE_DEPENDS_QTGUI_PYTHON "PyQt4" "PyQwt")
+SET(PACKAGE_DEPENDS_GRC "python" "numpy" "gtk2" "python-lxml" "python-cheetah")
+SET(PACKAGE_DEPENDS_WXGUI "wxGTK" "python" "numpy")
+SET(PACKAGE_DEPENDS_VIDEO_SDL_RUNTIME "SDL")
+SET(PACKAGE_DEPENDS_UHD_RUNTIME "uhd")
+SET(PACKAGE_DEPENDS_AUDIO_RUNTIME "pulseaudio" "alsa-lib" "jack-audio-connection-kit")
+SET(PACKAGE_DEPENDS_WAVELET_RUNTIME "gsl")
+SET(PACKAGE_DEPENDS_WAVELET_PYTHON "python" "numpy")
diff --git a/cmake/Packaging/Ubuntu-10.04.cmake b/cmake/Packaging/Ubuntu-10.04.cmake
index a7a60f6b80..3320073c6b 100644
--- a/cmake/Packaging/Ubuntu-10.04.cmake
+++ b/cmake/Packaging/Ubuntu-10.04.cmake
@@ -1,6 +1,6 @@
SET(PACKAGE_DEPENDS_GRUEL_RUNTIME "libboost-all-dev" "libc6")
SET(PACKAGE_DEPENDS_GRUEL_PYTHON "python")
-SET(PACKAGE_DEPENDS_CORE_RUNTIME "libfftw3-3" "libgsl0ldbl")
+SET(PACKAGE_DEPENDS_CORE_RUNTIME "libfftw3-3")
SET(PACKAGE_DEPENDS_QTGUI_RUNTIME "libqtcore4" "libqwt5-qt4")
SET(PACKAGE_DEPENDS_QTGUI_PYTHON "python-qt4" "python-qwt5-qt4")
SET(PACKAGE_DEPENDS_GRC "python" "python-numpy" "python-gtk2" "python-lxml" "python-cheetah")
@@ -8,3 +8,5 @@ SET(PACKAGE_DEPENDS_WXGUI "python-wxgtk2.8" "python" "python-numpy")
SET(PACKAGE_DEPENDS_VIDEO_SDL_RUNTIME "libsdl1.2debian")
SET(PACKAGE_DEPENDS_UHD_RUNTIME "uhd")
SET(PACKAGE_DEPENDS_AUDIO_RUNTIME "libpulse0" "alsa-base" "libjack0")
+SET(PACKAGE_DEPENDS_WAVELET_RUNTIME "libgsl0ldbl")
+SET(PACKAGE_DEPENDS_WAVELET_PYTHON "python" "python-numpy")
diff --git a/cmake/Packaging/Ubuntu-10.10.cmake b/cmake/Packaging/Ubuntu-10.10.cmake
index a7a60f6b80..3320073c6b 100644
--- a/cmake/Packaging/Ubuntu-10.10.cmake
+++ b/cmake/Packaging/Ubuntu-10.10.cmake
@@ -1,6 +1,6 @@
SET(PACKAGE_DEPENDS_GRUEL_RUNTIME "libboost-all-dev" "libc6")
SET(PACKAGE_DEPENDS_GRUEL_PYTHON "python")
-SET(PACKAGE_DEPENDS_CORE_RUNTIME "libfftw3-3" "libgsl0ldbl")
+SET(PACKAGE_DEPENDS_CORE_RUNTIME "libfftw3-3")
SET(PACKAGE_DEPENDS_QTGUI_RUNTIME "libqtcore4" "libqwt5-qt4")
SET(PACKAGE_DEPENDS_QTGUI_PYTHON "python-qt4" "python-qwt5-qt4")
SET(PACKAGE_DEPENDS_GRC "python" "python-numpy" "python-gtk2" "python-lxml" "python-cheetah")
@@ -8,3 +8,5 @@ SET(PACKAGE_DEPENDS_WXGUI "python-wxgtk2.8" "python" "python-numpy")
SET(PACKAGE_DEPENDS_VIDEO_SDL_RUNTIME "libsdl1.2debian")
SET(PACKAGE_DEPENDS_UHD_RUNTIME "uhd")
SET(PACKAGE_DEPENDS_AUDIO_RUNTIME "libpulse0" "alsa-base" "libjack0")
+SET(PACKAGE_DEPENDS_WAVELET_RUNTIME "libgsl0ldbl")
+SET(PACKAGE_DEPENDS_WAVELET_PYTHON "python" "python-numpy")
diff --git a/cmake/Packaging/Ubuntu-11.04.cmake b/cmake/Packaging/Ubuntu-11.04.cmake
index 71882b2e1f..c166bcf427 100644
--- a/cmake/Packaging/Ubuntu-11.04.cmake
+++ b/cmake/Packaging/Ubuntu-11.04.cmake
@@ -1,7 +1,7 @@
#set the debian package dependencies (parsed by our deb component maker)
SET(PACKAGE_DEPENDS_GRUEL_RUNTIME "libboost-all-dev" "libc6")
SET(PACKAGE_DEPENDS_GRUEL_PYTHON "python")
-SET(PACKAGE_DEPENDS_CORE_RUNTIME "libfftw3-3" "libgsl0ldbl")
+SET(PACKAGE_DEPENDS_CORE_RUNTIME "libfftw3-3")
SET(PACKAGE_DEPENDS_QTGUI_RUNTIME "libqtcore4" "libqwt5-qt4")
SET(PACKAGE_DEPENDS_QTGUI_PYTHON "python-qt4" "python-qwt5-qt4")
SET(PACKAGE_DEPENDS_GRC "python" "python-numpy" "python-gtk2" "python-lxml" "python-cheetah")
@@ -9,3 +9,5 @@ SET(PACKAGE_DEPENDS_WXGUI "python-wxgtk2.8")
SET(PACKAGE_DEPENDS_VIDEO_SDL_RUNTIME "libsdl1.2debian")
SET(PACKAGE_DEPENDS_UHD_RUNTIME "uhd")
SET(PACKAGE_DEPENDS_AUDIO_RUNTIME "libpulse0" "alsa-base" "libjack0")
+SET(PACKAGE_DEPENDS_WAVELET_RUNTIME "libgsl0ldbl")
+SET(PACKAGE_DEPENDS_WAVELET_PYTHON "python" "python-numpy")
diff --git a/cmake/Packaging/Ubuntu-11.10.cmake b/cmake/Packaging/Ubuntu-11.10.cmake
index dcb7b31783..702ce574f3 100644
--- a/cmake/Packaging/Ubuntu-11.10.cmake
+++ b/cmake/Packaging/Ubuntu-11.10.cmake
@@ -1,6 +1,6 @@
SET(PACKAGE_DEPENDS_GRUEL_RUNTIME "libboost-all-dev" "libc6")
SET(PACKAGE_DEPENDS_GRUEL_PYTHON "python" "python-numpy")
-SET(PACKAGE_DEPENDS_CORE_RUNTIME "libfftw3-3" "libgsl0ldbl")
+SET(PACKAGE_DEPENDS_CORE_RUNTIME "libfftw3-3")
SET(PACKAGE_DEPENDS_QTGUI_RUNTIME "libqtcore4" "libqwt6")
SET(PACKAGE_DEPENDS_QTGUI_PYTHON "python-qt4" "python-qwt5-qt4")
SET(PACKAGE_DEPENDS_GRC "python" "python-numpy" "python-gtk2" "python-lxml" "python-cheetah")
@@ -8,3 +8,5 @@ SET(PACKAGE_DEPENDS_WXGUI "python-wxgtk2.8")
SET(PACKAGE_DEPENDS_VIDEO_SDL_RUNTIME "libsdl1.2debian")
SET(PACKAGE_DEPENDS_UHD_RUNTIME "uhd")
SET(PACKAGE_DEPENDS_AUDIO_RUNTIME "libpulse0" "alsa-base" "libjack0")
+SET(PACKAGE_DEPENDS_WAVELET_RUNTIME "libgsl0ldbl")
+SET(PACKAGE_DEPENDS_WAVELET_PYTHON "python" "python-numpy")
diff --git a/cmake/Packaging/Ubuntu-12.04.cmake b/cmake/Packaging/Ubuntu-12.04.cmake
new file mode 100644
index 0000000000..702ce574f3
--- /dev/null
+++ b/cmake/Packaging/Ubuntu-12.04.cmake
@@ -0,0 +1,12 @@
+SET(PACKAGE_DEPENDS_GRUEL_RUNTIME "libboost-all-dev" "libc6")
+SET(PACKAGE_DEPENDS_GRUEL_PYTHON "python" "python-numpy")
+SET(PACKAGE_DEPENDS_CORE_RUNTIME "libfftw3-3")
+SET(PACKAGE_DEPENDS_QTGUI_RUNTIME "libqtcore4" "libqwt6")
+SET(PACKAGE_DEPENDS_QTGUI_PYTHON "python-qt4" "python-qwt5-qt4")
+SET(PACKAGE_DEPENDS_GRC "python" "python-numpy" "python-gtk2" "python-lxml" "python-cheetah")
+SET(PACKAGE_DEPENDS_WXGUI "python-wxgtk2.8")
+SET(PACKAGE_DEPENDS_VIDEO_SDL_RUNTIME "libsdl1.2debian")
+SET(PACKAGE_DEPENDS_UHD_RUNTIME "uhd")
+SET(PACKAGE_DEPENDS_AUDIO_RUNTIME "libpulse0" "alsa-base" "libjack0")
+SET(PACKAGE_DEPENDS_WAVELET_RUNTIME "libgsl0ldbl")
+SET(PACKAGE_DEPENDS_WAVELET_PYTHON "python" "python-numpy")
diff --git a/docs/doxygen/doxyxml/doxyindex.py b/docs/doxygen/doxyxml/doxyindex.py
index 84bc7b88c3..304109a8e5 100644
--- a/docs/doxygen/doxyxml/doxyindex.py
+++ b/docs/doxygen/doxyxml/doxyindex.py
@@ -80,12 +80,28 @@ class DoxyCompMem(Base):
self._data['brief_description'] = bd
self._data['detailed_description'] = dd
+ def set_parameters(self, data):
+ vs = [ddc.value for ddc in data.detaileddescription.content_]
+ pls = []
+ for v in vs:
+ if hasattr(v, 'parameterlist'):
+ pls += v.parameterlist
+ pis = []
+ for pl in pls:
+ pis += pl.parameteritem
+ dpis = []
+ for pi in pis:
+ dpi = DoxyParameterItem(pi)
+ dpi._parse()
+ dpis.append(dpi)
+ self._data['params'] = dpis
+
+
class DoxyCompound(DoxyCompMem):
pass
class DoxyMember(DoxyCompMem):
pass
-
class DoxyFunction(DoxyMember):
@@ -98,10 +114,13 @@ class DoxyFunction(DoxyMember):
return
super(DoxyFunction, self)._parse()
self.set_descriptions(self._parse_data)
- self._data['params'] = []
- prms = self._parse_data.param
- for prm in prms:
- self._data['params'].append(DoxyParam(prm))
+ self.set_parameters(self._parse_data)
+ if not self._data['params']:
+ # If the params weren't set by a comment then just grab the names.
+ self._data['params'] = []
+ prms = self._parse_data.param
+ for prm in prms:
+ self._data['params'].append(DoxyParam(prm))
brief_description = property(lambda self: self.data()['brief_description'])
detailed_description = property(lambda self: self.data()['detailed_description'])
@@ -121,9 +140,18 @@ class DoxyParam(DoxyMember):
self.set_descriptions(self._parse_data)
self._data['declname'] = self._parse_data.declname
+ @property
+ def description(self):
+ descriptions = []
+ if self.brief_description:
+ descriptions.append(self.brief_description)
+ if self.detailed_description:
+ descriptions.append(self.detailed_description)
+ return '\n\n'.join(descriptions)
+
brief_description = property(lambda self: self.data()['brief_description'])
detailed_description = property(lambda self: self.data()['detailed_description'])
- declname = property(lambda self: self.data()['declname'])
+ name = property(lambda self: self.data()['declname'])
class DoxyParameterItem(DoxyMember):
"""A different representation of a parameter in Doxygen."""
@@ -165,22 +193,6 @@ class DoxyClass(DoxyCompound):
# We just ignore this for now.
self.process_memberdefs()
- def set_parameters(self, data):
- vs = [ddc.value for ddc in data.detaileddescription.content_]
- pls = []
- for v in vs:
- if hasattr(v, 'parameterlist'):
- pls += v.parameterlist
- pis = []
- for pl in pls:
- pis += pl.parameteritem
- dpis = []
- for pi in pis:
- dpi = DoxyParameterItem(pi)
- dpi._parse()
- dpis.append(dpi)
- self._data['params'] = dpis
-
brief_description = property(lambda self: self.data()['brief_description'])
detailed_description = property(lambda self: self.data()['detailed_description'])
params = property(lambda self: self.data()['params'])
diff --git a/docs/doxygen/other/volk_guide.dox b/docs/doxygen/other/volk_guide.dox
index 24882ed1a6..0e444ebbaf 100644
--- a/docs/doxygen/other/volk_guide.dox
+++ b/docs/doxygen/other/volk_guide.dox
@@ -63,7 +63,7 @@ calls with:
\code
const int alignment_multiple =
volk_get_alignment() / output_item_size;
- set_alignment(alignment_multiple);
+ set_alignment(std::max(1,alignment_multiple));
\endcode
The Volk function 'volk_get_alignment' provides the alignment of the
diff --git a/docs/doxygen/swig_doc.py b/docs/doxygen/swig_doc.py
index 414748bbae..9277470984 100644
--- a/docs/doxygen/swig_doc.py
+++ b/docs/doxygen/swig_doc.py
@@ -29,7 +29,8 @@ python docstrings.
import sys, time
-from doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile, base
+from doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile
+from doxyxml import DoxyOther, base
def py_name(name):
bits = name.split('_')
@@ -54,8 +55,27 @@ class Block(object):
return False
friendname = make_name(item.name())
is_a_block = item.has_member(friendname, DoxyFriend)
+ # But now sometimes the make function isn't a friend so check again.
+ if not is_a_block:
+ is_a_block = di.has_member(friendname, DoxyFunction)
return is_a_block
+class Block2(object):
+ """
+ Checks if doxyxml produced objects correspond to a new style
+ gnuradio block.
+ """
+
+ @classmethod
+ def includes(cls, item):
+ if not isinstance(item, DoxyClass):
+ return False
+ # Check for a parsing error.
+ if item.error():
+ return False
+ is_a_block2 = item.has_member('make', DoxyFunction) and item.has_member('sptr', DoxyOther)
+ return is_a_block2
+
def utoascii(text):
"""
@@ -141,15 +161,18 @@ def make_func_entry(func, name=None, description=None, params=None):
return make_entry(func, name=name, description=description, params=params)
-def make_class_entry(klass, description=None):
+def make_class_entry(klass, description=None, ignored_methods=[], params=None):
"""
Create a class docstring for a swig interface file.
"""
+ if params is None:
+ params = klass.params
output = []
- output.append(make_entry(klass, description=description, params=klass.params))
+ output.append(make_entry(klass, description=description, params=params))
for func in klass.in_category(DoxyFunction):
- name = klass.name() + '::' + func.name()
- output.append(make_func_entry(func, name=name))
+ if func.name() not in ignored_methods:
+ name = klass.name() + '::' + func.name()
+ output.append(make_func_entry(func, name=name))
return "\n\n".join(output)
@@ -183,11 +206,32 @@ def make_block_entry(di, block):
# the make function.
output = []
output.append(make_class_entry(block, description=super_description))
- creator = block.get_member(block.name(), DoxyFunction)
output.append(make_func_entry(make_func, description=super_description,
params=block.params))
return "\n\n".join(output)
+def make_block2_entry(di, block):
+ """
+ Create class and function docstrings of a new style gnuradio block for a
+ swig interface file.
+ """
+ descriptions = []
+ # For new style blocks all the relevant documentation should be
+ # associated with the 'make' method.
+ make_func = block.get_member('make', DoxyFunction)
+ description = combine_descriptions(make_func)
+ # Associate the combined description with the class and
+ # the make function.
+ output = []
+ #output.append(make_class_entry(
+ # block, description=description,
+ # ignored_methods=['make'], params=make_func.params))
+ makename = block.name() + '::make'
+ output.append(make_func_entry(
+ make_func, name=makename, description=description,
+ params=make_func.params))
+ return "\n\n".join(output)
+
def wait_if_necessary(tries, swigdocfilename, item=None):
if item is not None:
extra = ', item {0}'.format(item.name())
@@ -223,6 +267,7 @@ def make_swig_interface_file(di, swigdocfilename, custom_output=None, tries=0):
while(1):
try:
blocks = di.in_category(Block)
+ blocks2 = di.in_category(Block2)
except:
tries, try_again = wait_if_necessary(tries, swigdocfilename)
if not try_again:
@@ -246,10 +291,28 @@ def make_swig_interface_file(di, swigdocfilename, custom_output=None, tries=0):
raise
else:
break
+ for block in blocks2:
+ while(1):
+ try:
+ make_func = block.get_member('make', DoxyFunction)
+ make_func_name = block.name() +'::make'
+ # Don't want to risk writing to output twice.
+ if make_func_name not in make_funcs:
+ make_funcs.add(make_func_name)
+ output.append(make_block2_entry(di, block))
+ except block.ParsingError:
+ sys.stderr.write('Parsing error for block {0}\n'.format(block.name()))
+ except:
+ tries, try_again = wait_if_necessary(tries, swigdocfilename, block)
+ if not try_again:
+ raise
+ else:
+ break
# Create docstrings for functions
# Don't include the make functions since they have already been dealt with.
- funcs = [f for f in di.in_category(DoxyFunction) if f.name() not in make_funcs]
+ funcs = [f for f in di.in_category(DoxyFunction)
+ if f.name() not in make_funcs and not f.name().startswith('std::')]
for f in funcs:
try:
output.append(make_func_entry(f))
@@ -258,7 +321,9 @@ def make_swig_interface_file(di, swigdocfilename, custom_output=None, tries=0):
# Create docstrings for classes
block_names = [block.name() for block in blocks]
- klasses = [k for k in di.in_category(DoxyClass) if k.name() not in block_names]
+ block_names += [block.name() for block in blocks2]
+ klasses = [k for k in di.in_category(DoxyClass)
+ if k.name() not in block_names and not k.name().startswith('std::')]
for k in klasses:
try:
output.append(make_class_entry(k))
diff --git a/docs/sphinx/README b/docs/sphinx/README
index c3ac382648..0ae3a43f84 100644
--- a/docs/sphinx/README
+++ b/docs/sphinx/README
@@ -48,7 +48,7 @@ examples.
under the "Slicing and Dicing Streams" subheading.
Edit file gnuradio/docs/sphinx/source/gr/slicedice_blk.rst and add
the line
- >.. autoblock:: gnuradio.gr.myslicer
+ >.. autooldblock:: gnuradio.gr.myslicer
2) Adding a new python hierarchical block gnuradio.digital.mymod
Edit file gnruadio/docs/sphinx/source/digital/index.rst and add the
@@ -63,7 +63,10 @@ examples.
a python hierarchical signal processing block so that it can format
it appropriately.
-The process for documenting objects that are not signal processing blocks is
-similar but rather than using the 'autoblock' and 'autopyblock' directives
-the standard sphinx directives such as 'autofunction' and 'autoclass' can
-be used. \ No newline at end of file
+The process for documenting objects that are not signal processing
+blocks is similar but rather than using the 'autooldblock', and
+'autopyblock' directives the standard sphinx directives such as
+'autofunction' and 'autoclass' can be used.
+
+Finally for signal processing blocks using the 3.7 style the directive
+'autoblock' rather than 'autooldblock' can be used. \ No newline at end of file
diff --git a/docs/sphinx/gnuradio_sphinx.py b/docs/sphinx/gnuradio_sphinx.py
index 6f35a6fce9..e8ca867f8c 100644
--- a/docs/sphinx/gnuradio_sphinx.py
+++ b/docs/sphinx/gnuradio_sphinx.py
@@ -15,6 +15,7 @@ def setup(sp):
sp.connect('autodoc-process-signature', fix_signature)
sp.connect('autodoc-process-docstring', remove_lines)
# Add node to autodocument signal-processing blocks.
+ sp.add_autodocumenter(OldBlockDocumenter)
sp.add_autodocumenter(BlockDocumenter)
sp.add_autodocumenter(PyBlockDocumenter)
@@ -105,9 +106,10 @@ common_block_members =[
'thisown',
'to_basic_block',
'unique_id',
+ 'make',
]
-class BlockDocumenter(FunctionDocumenter):
+class OldBlockDocumenter(FunctionDocumenter):
"""
Specialized Documenter subclass for gnuradio blocks.
@@ -115,13 +117,13 @@ class BlockDocumenter(FunctionDocumenter):
with the wrapped sptr (e.g. gr.gr_head_sptr) to keep the documentation
tidier.
"""
- objtype = 'block'
+ objtype = 'oldblock'
directivetype = 'function'
# Don't want to use this for generic functions for give low priority.
priority = -10
def __init__(self, *args, **kwargs):
- super(BlockDocumenter, self).__init__(*args, **kwargs)
+ super(OldBlockDocumenter, self).__init__(*args, **kwargs)
# Get class name
bits = self.name.split('.')
if len(bits) != 3 or bits[0] != 'gnuradio':
@@ -129,6 +131,36 @@ class BlockDocumenter(FunctionDocumenter):
sptr_name = 'gnuradio.{0}.{0}_{1}_sptr'.format(bits[1], bits[2])
# Create a Class Documenter to create documentation for the classes members.
self.classdoccer = ClassDocumenter(self.directive, sptr_name, indent=self.content_indent)
+ self.classdoccer.doc_as_attr = False
+ self.classdoccer.real_modname = self.classdoccer.get_real_modname()
+ self.classdoccer.options.members = ALL
+ self.classdoccer.options.exclude_members = common_block_members
+ self.classdoccer.parse_name()
+ self.classdoccer.import_object()
+
+ def document_members(self, *args, **kwargs):
+ return self.classdoccer.document_members(*args, **kwargs)
+
+class BlockDocumenter(FunctionDocumenter):
+ """
+ Specialized Documenter subclass for new style gnuradio blocks.
+
+ It merges together the documentation for the generator function (e.g. wavelet.squash_ff)
+ with the wrapped sptr (e.g. wavelet.squash_ff_sptr) to keep the documentation
+ tidier.
+ """
+ objtype = 'block'
+ directivetype = 'function'
+ # Don't want to use this for generic functions for give low priority.
+ priority = -10
+
+ def __init__(self, *args, **kwargs):
+ super(BlockDocumenter, self).__init__(*args, **kwargs)
+ # Get class name
+ sptr_name = self.name + '_sptr'
+ # Create a Class Documenter to create documentation for the classes members.
+ self.classdoccer = ClassDocumenter(self.directive, sptr_name, indent=self.content_indent)
+ self.classdoccer.doc_as_attr = False
self.classdoccer.real_modname = self.classdoccer.get_real_modname()
self.classdoccer.options.members = ALL
self.classdoccer.options.exclude_members = common_block_members
diff --git a/docs/sphinx/source/atsc/blks.rst b/docs/sphinx/source/atsc/blks.rst
index ce26f095b1..6f51a22876 100644
--- a/docs/sphinx/source/atsc/blks.rst
+++ b/docs/sphinx/source/atsc/blks.rst
@@ -1,20 +1,20 @@
gnuradio.atsc: Signal Processing Blocks
=======================================
-.. autoblock:: gnuradio.atsc.bit_timing_loop
-.. autoblock:: gnuradio.atsc.deinterleaver
-.. autoblock:: gnuradio.atsc.depad
-.. autoblock:: gnuradio.atsc.derandomizer
-.. autoblock:: gnuradio.atsc.ds_to_softds
-.. autoblock:: gnuradio.atsc.equalizer
-.. autoblock:: gnuradio.atsc.field_sync_demux
-.. autoblock:: gnuradio.atsc.field_sync_mux
-.. autoblock:: gnuradio.atsc.fpll
-.. autoblock:: gnuradio.atsc.fs_checker
-.. autoblock:: gnuradio.atsc.interleaver
-.. autoblock:: gnuradio.atsc.pad
-.. autoblock:: gnuradio.atsc.randomizer
-.. autoblock:: gnuradio.atsc.rs_decoder
-.. autoblock:: gnuradio.atsc.rs_encoder
-.. autoblock:: gnuradio.atsc.trellis_encoder
-.. autoblock:: gnuradio.atsc.viterbi_decoder
+.. autooldblock:: gnuradio.atsc.bit_timing_loop
+.. autooldblock:: gnuradio.atsc.deinterleaver
+.. autooldblock:: gnuradio.atsc.depad
+.. autooldblock:: gnuradio.atsc.derandomizer
+.. autooldblock:: gnuradio.atsc.ds_to_softds
+.. autooldblock:: gnuradio.atsc.equalizer
+.. autooldblock:: gnuradio.atsc.field_sync_demux
+.. autooldblock:: gnuradio.atsc.field_sync_mux
+.. autooldblock:: gnuradio.atsc.fpll
+.. autooldblock:: gnuradio.atsc.fs_checker
+.. autooldblock:: gnuradio.atsc.interleaver
+.. autooldblock:: gnuradio.atsc.pad
+.. autooldblock:: gnuradio.atsc.randomizer
+.. autooldblock:: gnuradio.atsc.rs_decoder
+.. autooldblock:: gnuradio.atsc.rs_encoder
+.. autooldblock:: gnuradio.atsc.trellis_encoder
+.. autooldblock:: gnuradio.atsc.viterbi_decoder
diff --git a/docs/sphinx/source/audio/index.rst b/docs/sphinx/source/audio/index.rst
index 31d53567b8..d0bc4f3c08 100644
--- a/docs/sphinx/source/audio/index.rst
+++ b/docs/sphinx/source/audio/index.rst
@@ -3,5 +3,5 @@ gnuradio.audio
.. automodule:: gnuradio.audio
-.. autoblock:: gnuradio.audio.source
-.. autoblock:: gnuradio.audio.sink
+.. autooldblock:: gnuradio.audio.source
+.. autooldblock:: gnuradio.audio.sink
diff --git a/docs/sphinx/source/digital/blocks.rst b/docs/sphinx/source/digital/blocks.rst
index 2ac228d4ea..68ec8dad1c 100644
--- a/docs/sphinx/source/digital/blocks.rst
+++ b/docs/sphinx/source/digital/blocks.rst
@@ -1,22 +1,22 @@
gnuradio.digital: Signal Processing Blocks
==========================================
-.. autoblock:: gnuradio.digital.fll_band_edge_cc
-.. autoblock:: gnuradio.digital.kurtotic_equalizer_cc
-.. autoblock:: gnuradio.digital.lms_dd_equalizer_cc
-.. autoblock:: gnuradio.digital.mpsk_receiver_cc
-.. autoblock:: gnuradio.digital.mpsk_snr_est_cc
-.. autoblock:: gnuradio.digital.clock_recovery_mm_cc
-.. autoblock:: gnuradio.digital.clock_recovery_mm_ff
-.. autoblock:: gnuradio.digital.constellation_decoder_cb
-.. autoblock:: gnuradio.digital.constellation_receiver_cb
-.. autoblock:: gnuradio.digital.correlate_access_code_bb
-.. autoblock:: gnuradio.digital.costas_loop_cc
-.. autoblock:: gnuradio.digital.cma_equalizer_cc
-.. autoblock:: gnuradio.digital.binary_slicer_fb
-.. autoblock:: gnuradio.digital.gmskmod_bc
-.. autoblock:: gnuradio.digital.probe_mpsk_snr_est_c
-.. autoblock:: gnuradio.digital.cpmmod_bc
+.. autooldblock:: gnuradio.digital.fll_band_edge_cc
+.. autooldblock:: gnuradio.digital.kurtotic_equalizer_cc
+.. autooldblock:: gnuradio.digital.lms_dd_equalizer_cc
+.. autooldblock:: gnuradio.digital.mpsk_receiver_cc
+.. autooldblock:: gnuradio.digital.mpsk_snr_est_cc
+.. autooldblock:: gnuradio.digital.clock_recovery_mm_cc
+.. autooldblock:: gnuradio.digital.clock_recovery_mm_ff
+.. autooldblock:: gnuradio.digital.constellation_decoder_cb
+.. autooldblock:: gnuradio.digital.constellation_receiver_cb
+.. autooldblock:: gnuradio.digital.correlate_access_code_bb
+.. autooldblock:: gnuradio.digital.costas_loop_cc
+.. autooldblock:: gnuradio.digital.cma_equalizer_cc
+.. autooldblock:: gnuradio.digital.binary_slicer_fb
+.. autooldblock:: gnuradio.digital.gmskmod_bc
+.. autooldblock:: gnuradio.digital.probe_mpsk_snr_est_c
+.. autooldblock:: gnuradio.digital.cpmmod_bc
.. autopyblock:: gnuradio.digital.generic_demod
.. autopyblock:: gnuradio.digital.generic_mod
.. autopyblock:: gnuradio.digital.bpsk.dbpsk_demod
diff --git a/docs/sphinx/source/fft.rst b/docs/sphinx/source/fft.rst
new file mode 100644
index 0000000000..79a0a4ed2a
--- /dev/null
+++ b/docs/sphinx/source/fft.rst
@@ -0,0 +1,8 @@
+gnuradio.fft
+============
+
+.. automodule:: gnuradio.fft
+
+.. autoblock:: gnuradio.fft.fft_vcc
+.. autoblock:: gnuradio.fft.fft_vfc
+.. autoblock:: gnuradio.fft.goertzel_fc
diff --git a/docs/sphinx/source/gr/coding_blk.rst b/docs/sphinx/source/gr/coding_blk.rst
index 87196a5aeb..e50b990bcd 100644
--- a/docs/sphinx/source/gr/coding_blk.rst
+++ b/docs/sphinx/source/gr/coding_blk.rst
@@ -1,11 +1,11 @@
gnuradio.gr: Information Coding and Decoding
============================================
-.. autoblock:: gnuradio.gr.additive_scrambler_bb
-.. autoblock:: gnuradio.gr.descrambler_bb
-.. autoblock:: gnuradio.gr.diff_decoder_bb
-.. autoblock:: gnuradio.gr.diff_encoder_bb
-.. autoblock:: gnuradio.gr.fake_channel_encoder_pp
-.. autoblock:: gnuradio.gr.fake_channel_decoder_pp
-.. autoblock:: gnuradio.gr.map_bb
-.. autoblock:: gnuradio.gr.scrambler_bb
+.. autooldblock:: gnuradio.gr.additive_scrambler_bb
+.. autooldblock:: gnuradio.gr.descrambler_bb
+.. autooldblock:: gnuradio.gr.diff_decoder_bb
+.. autooldblock:: gnuradio.gr.diff_encoder_bb
+.. autooldblock:: gnuradio.gr.fake_channel_encoder_pp
+.. autooldblock:: gnuradio.gr.fake_channel_decoder_pp
+.. autooldblock:: gnuradio.gr.map_bb
+.. autooldblock:: gnuradio.gr.scrambler_bb
diff --git a/docs/sphinx/source/gr/converter_blk.rst b/docs/sphinx/source/gr/converter_blk.rst
index b0ddd1d8a9..790109a94f 100644
--- a/docs/sphinx/source/gr/converter_blk.rst
+++ b/docs/sphinx/source/gr/converter_blk.rst
@@ -1,32 +1,32 @@
gnuradio.gr: Type Conversions
=============================
-.. autoblock:: gnuradio.gr.bytes_to_syms
-.. autoblock:: gnuradio.gr.char_to_float
-.. autoblock:: gnuradio.gr.complex_to_interleaved_short
-.. autoblock:: gnuradio.gr.complex_to_float
-.. autoblock:: gnuradio.gr.complex_to_real
-.. autoblock:: gnuradio.gr.complex_to_imag
-.. autoblock:: gnuradio.gr.complex_to_mag
-.. autoblock:: gnuradio.gr.complex_to_mag_squared
-.. autoblock:: gnuradio.gr.complex_to_arg
-.. autoblock:: gnuradio.gr.float_to_char
-.. autoblock:: gnuradio.gr.float_to_complex
-.. autoblock:: gnuradio.gr.float_to_short
-.. autoblock:: gnuradio.gr.float_to_uchar
-.. autoblock:: gnuradio.gr.interleaved_short_to_complex
-.. autoblock:: gnuradio.gr.short_to_float
-.. autoblock:: gnuradio.gr.uchar_to_float
-.. autoblock:: gnuradio.gr.unpack_k_bits_bb
-.. autoblock:: gnuradio.gr.chunks_to_symbols_bc
-.. autoblock:: gnuradio.gr.chunks_to_symbols_bf
-.. autoblock:: gnuradio.gr.chunks_to_symbols_ic
-.. autoblock:: gnuradio.gr.chunks_to_symbols_if
-.. autoblock:: gnuradio.gr.chunks_to_symbols_sc
-.. autoblock:: gnuradio.gr.chunks_to_symbols_sf
-.. autoblock:: gnuradio.gr.packed_to_unpacked_bb
-.. autoblock:: gnuradio.gr.packed_to_unpacked_ii
-.. autoblock:: gnuradio.gr.packed_to_unpacked_ss
-.. autoblock:: gnuradio.gr.unpacked_to_packed_bb
-.. autoblock:: gnuradio.gr.unpacked_to_packed_ii
-.. autoblock:: gnuradio.gr.unpacked_to_packed_ss
+.. autooldblock:: gnuradio.gr.bytes_to_syms
+.. autooldblock:: gnuradio.gr.char_to_float
+.. autooldblock:: gnuradio.gr.complex_to_interleaved_short
+.. autooldblock:: gnuradio.gr.complex_to_float
+.. autooldblock:: gnuradio.gr.complex_to_real
+.. autooldblock:: gnuradio.gr.complex_to_imag
+.. autooldblock:: gnuradio.gr.complex_to_mag
+.. autooldblock:: gnuradio.gr.complex_to_mag_squared
+.. autooldblock:: gnuradio.gr.complex_to_arg
+.. autooldblock:: gnuradio.gr.float_to_char
+.. autooldblock:: gnuradio.gr.float_to_complex
+.. autooldblock:: gnuradio.gr.float_to_short
+.. autooldblock:: gnuradio.gr.float_to_uchar
+.. autooldblock:: gnuradio.gr.interleaved_short_to_complex
+.. autooldblock:: gnuradio.gr.short_to_float
+.. autooldblock:: gnuradio.gr.uchar_to_float
+.. autooldblock:: gnuradio.gr.unpack_k_bits_bb
+.. autooldblock:: gnuradio.gr.chunks_to_symbols_bc
+.. autooldblock:: gnuradio.gr.chunks_to_symbols_bf
+.. autooldblock:: gnuradio.gr.chunks_to_symbols_ic
+.. autooldblock:: gnuradio.gr.chunks_to_symbols_if
+.. autooldblock:: gnuradio.gr.chunks_to_symbols_sc
+.. autooldblock:: gnuradio.gr.chunks_to_symbols_sf
+.. autooldblock:: gnuradio.gr.packed_to_unpacked_bb
+.. autooldblock:: gnuradio.gr.packed_to_unpacked_ii
+.. autooldblock:: gnuradio.gr.packed_to_unpacked_ss
+.. autooldblock:: gnuradio.gr.unpacked_to_packed_bb
+.. autooldblock:: gnuradio.gr.unpacked_to_packed_ii
+.. autooldblock:: gnuradio.gr.unpacked_to_packed_ss
diff --git a/docs/sphinx/source/gr/demodulation_blk.rst b/docs/sphinx/source/gr/demodulation_blk.rst
index e5a9354340..4f800b642b 100644
--- a/docs/sphinx/source/gr/demodulation_blk.rst
+++ b/docs/sphinx/source/gr/demodulation_blk.rst
@@ -1,4 +1,4 @@
gnuradio.gr: Demodulation
=========================
-.. autoblock:: gnuradio.gr.quadrature_demod_cf
+.. autooldblock:: gnuradio.gr.quadrature_demod_cf
diff --git a/docs/sphinx/source/gr/dft_blk.rst b/docs/sphinx/source/gr/dft_blk.rst
index a93119969b..4ac1d2e621 100644
--- a/docs/sphinx/source/gr/dft_blk.rst
+++ b/docs/sphinx/source/gr/dft_blk.rst
@@ -1,6 +1,6 @@
gnuradio.gr: Fourier Transform
==============================
-.. autoblock:: gnuradio.gr.goertzel_fc
-.. autoblock:: gnuradio.gr.fft_vcc
-.. autoblock:: gnuradio.gr.fft_vfc
+.. autooldblock:: gnuradio.gr.goertzel_fc
+.. autooldblock:: gnuradio.gr.fft_vcc
+.. autooldblock:: gnuradio.gr.fft_vfc
diff --git a/docs/sphinx/source/gr/filter_blk.rst b/docs/sphinx/source/gr/filter_blk.rst
index 767ee4b741..a73ddda2a8 100644
--- a/docs/sphinx/source/gr/filter_blk.rst
+++ b/docs/sphinx/source/gr/filter_blk.rst
@@ -1,46 +1,46 @@
gnuradio.gr: Filters
====================
-.. autoblock:: gnuradio.gr.fft_filter_ccc
-.. autoblock:: gnuradio.gr.fft_filter_fff
-.. autoblock:: gnuradio.gr.filter_delay_fc
-.. autoblock:: gnuradio.gr.fir_filter_ccc
-.. autoblock:: gnuradio.gr.fir_filter_ccf
-.. autoblock:: gnuradio.gr.fir_filter_fcc
-.. autoblock:: gnuradio.gr.fir_filter_fff
-.. autoblock:: gnuradio.gr.fir_filter_fsf
-.. autoblock:: gnuradio.gr.fir_filter_scc
-.. autoblock:: gnuradio.gr.fractional_interpolator_cc
-.. autoblock:: gnuradio.gr.fractional_interpolator_ff
-.. autoblock:: gnuradio.gr.freq_xlating_fir_filter_ccc
-.. autoblock:: gnuradio.gr.freq_xlating_fir_filter_ccf
-.. autoblock:: gnuradio.gr.freq_xlating_fir_filter_fcc
-.. autoblock:: gnuradio.gr.freq_xlating_fir_filter_fcf
-.. autoblock:: gnuradio.gr.freq_xlating_fir_filter_scc
-.. autoblock:: gnuradio.gr.freq_xlating_fir_filter_scf
-.. autoblock:: gnuradio.gr.hilbert_fc
-.. autoblock:: gnuradio.gr.iir_filter_ffd
-.. autoblock:: gnuradio.gr.interp_fir_filter_ccc
-.. autoblock:: gnuradio.gr.interp_fir_filter_ccf
-.. autoblock:: gnuradio.gr.interp_fir_filter_fcc
-.. autoblock:: gnuradio.gr.interp_fir_filter_fff
-.. autoblock:: gnuradio.gr.interp_fir_filter_fsf
-.. autoblock:: gnuradio.gr.interp_fir_filter_scc
-.. autoblock:: gnuradio.gr.rational_resampler_base_ccc
-.. autoblock:: gnuradio.gr.rational_resampler_base_ccf
-.. autoblock:: gnuradio.gr.rational_resampler_base_fcc
-.. autoblock:: gnuradio.gr.rational_resampler_base_fff
-.. autoblock:: gnuradio.gr.rational_resampler_base_fsf
-.. autoblock:: gnuradio.gr.rational_resampler_base_scc
-.. autoblock:: gnuradio.gr.single_pole_iir_filter_cc
-.. autoblock:: gnuradio.gr.single_pole_iir_filter_ff
-.. autoblock:: gnuradio.gr.moving_average_cc
-.. autoblock:: gnuradio.gr.moving_average_ff
-.. autoblock:: gnuradio.gr.moving_average_ii
-.. autoblock:: gnuradio.gr.moving_average_ss
-.. autoblock:: gnuradio.gr.pfb_arb_resampler_ccf
-.. autoblock:: gnuradio.gr.pfb_channelizer_ccf
-.. autoblock:: gnuradio.gr.pfb_clock_sync_ccf
-.. autoblock:: gnuradio.gr.pfb_clock_sync_fff
-.. autoblock:: gnuradio.gr.pfb_decimator_ccf
-.. autoblock:: gnuradio.gr.pfb_interpolator_ccf
+.. autooldblock:: gnuradio.gr.fft_filter_ccc
+.. autooldblock:: gnuradio.gr.fft_filter_fff
+.. autooldblock:: gnuradio.gr.filter_delay_fc
+.. autooldblock:: gnuradio.gr.fir_filter_ccc
+.. autooldblock:: gnuradio.gr.fir_filter_ccf
+.. autooldblock:: gnuradio.gr.fir_filter_fcc
+.. autooldblock:: gnuradio.gr.fir_filter_fff
+.. autooldblock:: gnuradio.gr.fir_filter_fsf
+.. autooldblock:: gnuradio.gr.fir_filter_scc
+.. autooldblock:: gnuradio.gr.fractional_interpolator_cc
+.. autooldblock:: gnuradio.gr.fractional_interpolator_ff
+.. autooldblock:: gnuradio.gr.freq_xlating_fir_filter_ccc
+.. autooldblock:: gnuradio.gr.freq_xlating_fir_filter_ccf
+.. autooldblock:: gnuradio.gr.freq_xlating_fir_filter_fcc
+.. autooldblock:: gnuradio.gr.freq_xlating_fir_filter_fcf
+.. autooldblock:: gnuradio.gr.freq_xlating_fir_filter_scc
+.. autooldblock:: gnuradio.gr.freq_xlating_fir_filter_scf
+.. autooldblock:: gnuradio.gr.hilbert_fc
+.. autooldblock:: gnuradio.gr.iir_filter_ffd
+.. autooldblock:: gnuradio.gr.interp_fir_filter_ccc
+.. autooldblock:: gnuradio.gr.interp_fir_filter_ccf
+.. autooldblock:: gnuradio.gr.interp_fir_filter_fcc
+.. autooldblock:: gnuradio.gr.interp_fir_filter_fff
+.. autooldblock:: gnuradio.gr.interp_fir_filter_fsf
+.. autooldblock:: gnuradio.gr.interp_fir_filter_scc
+.. autooldblock:: gnuradio.gr.rational_resampler_base_ccc
+.. autooldblock:: gnuradio.gr.rational_resampler_base_ccf
+.. autooldblock:: gnuradio.gr.rational_resampler_base_fcc
+.. autooldblock:: gnuradio.gr.rational_resampler_base_fff
+.. autooldblock:: gnuradio.gr.rational_resampler_base_fsf
+.. autooldblock:: gnuradio.gr.rational_resampler_base_scc
+.. autooldblock:: gnuradio.gr.single_pole_iir_filter_cc
+.. autooldblock:: gnuradio.gr.single_pole_iir_filter_ff
+.. autooldblock:: gnuradio.gr.moving_average_cc
+.. autooldblock:: gnuradio.gr.moving_average_ff
+.. autooldblock:: gnuradio.gr.moving_average_ii
+.. autooldblock:: gnuradio.gr.moving_average_ss
+.. autooldblock:: gnuradio.gr.pfb_arb_resampler_ccf
+.. autooldblock:: gnuradio.gr.pfb_channelizer_ccf
+.. autooldblock:: gnuradio.gr.pfb_clock_sync_ccf
+.. autooldblock:: gnuradio.gr.pfb_clock_sync_fff
+.. autooldblock:: gnuradio.gr.pfb_decimator_ccf
+.. autooldblock:: gnuradio.gr.pfb_interpolator_ccf
diff --git a/docs/sphinx/source/gr/level_blk.rst b/docs/sphinx/source/gr/level_blk.rst
index 77ba2270df..d6c565c65d 100644
--- a/docs/sphinx/source/gr/level_blk.rst
+++ b/docs/sphinx/source/gr/level_blk.rst
@@ -1,26 +1,26 @@
gnuradio.gr: Signal Level Control (AGC)
=======================================
-.. autoblock:: gnuradio.gr.agc2_cc
-.. autoblock:: gnuradio.gr.agc2_ff
-.. autoblock:: gnuradio.gr.agc_cc
-.. autoblock:: gnuradio.gr.agc_ff
-.. autoblock:: gnuradio.gr.ctcss_squelch_ff
-.. autoblock:: gnuradio.gr.dpll_bb
-.. autoblock:: gnuradio.gr.feedforward_agc_cc
-.. autoblock:: gnuradio.gr.peak_detector2_fb
-.. autoblock:: gnuradio.gr.pwr_squelch_cc
-.. autoblock:: gnuradio.gr.pwr_squelch_ff
-.. autoblock:: gnuradio.gr.regenerate_bb
-.. autoblock:: gnuradio.gr.simple_squelch_cc
-.. autoblock:: gnuradio.gr.mute_cc
-.. autoblock:: gnuradio.gr.mute_ff
-.. autoblock:: gnuradio.gr.mute_ii
-.. autoblock:: gnuradio.gr.mute_ss
-.. autoblock:: gnuradio.gr.peak_detector_fb
-.. autoblock:: gnuradio.gr.peak_detector_ib
-.. autoblock:: gnuradio.gr.peak_detector_sb
-.. autoblock:: gnuradio.gr.sample_and_hold_bb
-.. autoblock:: gnuradio.gr.sample_and_hold_ff
-.. autoblock:: gnuradio.gr.sample_and_hold_ii
-.. autoblock:: gnuradio.gr.sample_and_hold_ss
+.. autooldblock:: gnuradio.gr.agc2_cc
+.. autooldblock:: gnuradio.gr.agc2_ff
+.. autooldblock:: gnuradio.gr.agc_cc
+.. autooldblock:: gnuradio.gr.agc_ff
+.. autooldblock:: gnuradio.gr.ctcss_squelch_ff
+.. autooldblock:: gnuradio.gr.dpll_bb
+.. autooldblock:: gnuradio.gr.feedforward_agc_cc
+.. autooldblock:: gnuradio.gr.peak_detector2_fb
+.. autooldblock:: gnuradio.gr.pwr_squelch_cc
+.. autooldblock:: gnuradio.gr.pwr_squelch_ff
+.. autooldblock:: gnuradio.gr.regenerate_bb
+.. autooldblock:: gnuradio.gr.simple_squelch_cc
+.. autooldblock:: gnuradio.gr.mute_cc
+.. autooldblock:: gnuradio.gr.mute_ff
+.. autooldblock:: gnuradio.gr.mute_ii
+.. autooldblock:: gnuradio.gr.mute_ss
+.. autooldblock:: gnuradio.gr.peak_detector_fb
+.. autooldblock:: gnuradio.gr.peak_detector_ib
+.. autooldblock:: gnuradio.gr.peak_detector_sb
+.. autooldblock:: gnuradio.gr.sample_and_hold_bb
+.. autooldblock:: gnuradio.gr.sample_and_hold_ff
+.. autooldblock:: gnuradio.gr.sample_and_hold_ii
+.. autooldblock:: gnuradio.gr.sample_and_hold_ss
diff --git a/docs/sphinx/source/gr/math_blk.rst b/docs/sphinx/source/gr/math_blk.rst
index a2ef51922e..7b9437f995 100644
--- a/docs/sphinx/source/gr/math_blk.rst
+++ b/docs/sphinx/source/gr/math_blk.rst
@@ -1,59 +1,59 @@
gnuradio.gr: Mathematics
========================
-.. autoblock:: gnuradio.gr.conjugate_cc
-.. autoblock:: gnuradio.gr.nlog10_ff
-.. autoblock:: gnuradio.gr.rms_cf
-.. autoblock:: gnuradio.gr.rms_ff
-.. autoblock:: gnuradio.gr.add_cc
-.. autoblock:: gnuradio.gr.add_const_cc
-.. autoblock:: gnuradio.gr.add_const_ff
-.. autoblock:: gnuradio.gr.add_const_ii
-.. autoblock:: gnuradio.gr.add_const_sf
-.. autoblock:: gnuradio.gr.add_const_ss
-.. autoblock:: gnuradio.gr.add_const_vcc
-.. autoblock:: gnuradio.gr.add_const_vff
-.. autoblock:: gnuradio.gr.add_const_vii
-.. autoblock:: gnuradio.gr.add_const_vss
-.. autoblock:: gnuradio.gr.add_ff
-.. autoblock:: gnuradio.gr.add_ii
-.. autoblock:: gnuradio.gr.add_ss
-.. autoblock:: gnuradio.gr.and_bb
-.. autoblock:: gnuradio.gr.and_const_bb
-.. autoblock:: gnuradio.gr.and_const_ii
-.. autoblock:: gnuradio.gr.and_const_ss
-.. autoblock:: gnuradio.gr.and_ii
-.. autoblock:: gnuradio.gr.and_ss
-.. autoblock:: gnuradio.gr.divide_cc
-.. autoblock:: gnuradio.gr.divide_ff
-.. autoblock:: gnuradio.gr.divide_ii
-.. autoblock:: gnuradio.gr.divide_ss
-.. autoblock:: gnuradio.gr.integrate_cc
-.. autoblock:: gnuradio.gr.integrate_ff
-.. autoblock:: gnuradio.gr.integrate_ii
-.. autoblock:: gnuradio.gr.integrate_ss
-.. autoblock:: gnuradio.gr.multiply_cc
-.. autoblock:: gnuradio.gr.multiply_const_cc
-.. autoblock:: gnuradio.gr.multiply_const_ff
-.. autoblock:: gnuradio.gr.multiply_const_ii
-.. autoblock:: gnuradio.gr.multiply_const_ss
-.. autoblock:: gnuradio.gr.multiply_const_vcc
-.. autoblock:: gnuradio.gr.multiply_const_vff
-.. autoblock:: gnuradio.gr.multiply_const_vii
-.. autoblock:: gnuradio.gr.multiply_const_vss
-.. autoblock:: gnuradio.gr.multiply_ff
-.. autoblock:: gnuradio.gr.multiply_ii
-.. autoblock:: gnuradio.gr.multiply_ss
-.. autoblock:: gnuradio.gr.not_bb
-.. autoblock:: gnuradio.gr.not_ii
-.. autoblock:: gnuradio.gr.not_ss
-.. autoblock:: gnuradio.gr.or_bb
-.. autoblock:: gnuradio.gr.or_ii
-.. autoblock:: gnuradio.gr.or_ss
-.. autoblock:: gnuradio.gr.sub_cc
-.. autoblock:: gnuradio.gr.sub_ff
-.. autoblock:: gnuradio.gr.sub_ii
-.. autoblock:: gnuradio.gr.sub_ss
-.. autoblock:: gnuradio.gr.xor_bb
-.. autoblock:: gnuradio.gr.xor_ii
-.. autoblock:: gnuradio.gr.xor_ss
+.. autooldblock:: gnuradio.gr.conjugate_cc
+.. autooldblock:: gnuradio.gr.nlog10_ff
+.. autooldblock:: gnuradio.gr.rms_cf
+.. autooldblock:: gnuradio.gr.rms_ff
+.. autooldblock:: gnuradio.gr.add_cc
+.. autooldblock:: gnuradio.gr.add_const_cc
+.. autooldblock:: gnuradio.gr.add_const_ff
+.. autooldblock:: gnuradio.gr.add_const_ii
+.. autooldblock:: gnuradio.gr.add_const_sf
+.. autooldblock:: gnuradio.gr.add_const_ss
+.. autooldblock:: gnuradio.gr.add_const_vcc
+.. autooldblock:: gnuradio.gr.add_const_vff
+.. autooldblock:: gnuradio.gr.add_const_vii
+.. autooldblock:: gnuradio.gr.add_const_vss
+.. autooldblock:: gnuradio.gr.add_ff
+.. autooldblock:: gnuradio.gr.add_ii
+.. autooldblock:: gnuradio.gr.add_ss
+.. autooldblock:: gnuradio.gr.and_bb
+.. autooldblock:: gnuradio.gr.and_const_bb
+.. autooldblock:: gnuradio.gr.and_const_ii
+.. autooldblock:: gnuradio.gr.and_const_ss
+.. autooldblock:: gnuradio.gr.and_ii
+.. autooldblock:: gnuradio.gr.and_ss
+.. autooldblock:: gnuradio.gr.divide_cc
+.. autooldblock:: gnuradio.gr.divide_ff
+.. autooldblock:: gnuradio.gr.divide_ii
+.. autooldblock:: gnuradio.gr.divide_ss
+.. autooldblock:: gnuradio.gr.integrate_cc
+.. autooldblock:: gnuradio.gr.integrate_ff
+.. autooldblock:: gnuradio.gr.integrate_ii
+.. autooldblock:: gnuradio.gr.integrate_ss
+.. autooldblock:: gnuradio.gr.multiply_cc
+.. autooldblock:: gnuradio.gr.multiply_const_cc
+.. autooldblock:: gnuradio.gr.multiply_const_ff
+.. autooldblock:: gnuradio.gr.multiply_const_ii
+.. autooldblock:: gnuradio.gr.multiply_const_ss
+.. autooldblock:: gnuradio.gr.multiply_const_vcc
+.. autooldblock:: gnuradio.gr.multiply_const_vff
+.. autooldblock:: gnuradio.gr.multiply_const_vii
+.. autooldblock:: gnuradio.gr.multiply_const_vss
+.. autooldblock:: gnuradio.gr.multiply_ff
+.. autooldblock:: gnuradio.gr.multiply_ii
+.. autooldblock:: gnuradio.gr.multiply_ss
+.. autooldblock:: gnuradio.gr.not_bb
+.. autooldblock:: gnuradio.gr.not_ii
+.. autooldblock:: gnuradio.gr.not_ss
+.. autooldblock:: gnuradio.gr.or_bb
+.. autooldblock:: gnuradio.gr.or_ii
+.. autooldblock:: gnuradio.gr.or_ss
+.. autooldblock:: gnuradio.gr.sub_cc
+.. autooldblock:: gnuradio.gr.sub_ff
+.. autooldblock:: gnuradio.gr.sub_ii
+.. autooldblock:: gnuradio.gr.sub_ss
+.. autooldblock:: gnuradio.gr.xor_bb
+.. autooldblock:: gnuradio.gr.xor_ii
+.. autooldblock:: gnuradio.gr.xor_ss
diff --git a/docs/sphinx/source/gr/misc_blk.rst b/docs/sphinx/source/gr/misc_blk.rst
index f3bd2d943b..c69293056c 100644
--- a/docs/sphinx/source/gr/misc_blk.rst
+++ b/docs/sphinx/source/gr/misc_blk.rst
@@ -1,12 +1,12 @@
gnuradio.gr: Miscellaneous Blocks
=================================
-.. autoblock:: gnuradio.gr.copy
-.. autoblock:: gnuradio.gr.delay
-.. autoblock:: gnuradio.gr.kludge_copy
-.. autoblock:: gnuradio.gr.nop
-.. autoblock:: gnuradio.gr.pa_2x2_phase_combiner
-.. autoblock:: gnuradio.gr.repeat
-.. autoblock:: gnuradio.gr.threshold_ff
-.. autoblock:: gnuradio.gr.throttle
-.. autoblock:: gnuradio.gr.channel_model
+.. autooldblock:: gnuradio.gr.copy
+.. autooldblock:: gnuradio.gr.delay
+.. autooldblock:: gnuradio.gr.kludge_copy
+.. autooldblock:: gnuradio.gr.nop
+.. autooldblock:: gnuradio.gr.pa_2x2_phase_combiner
+.. autooldblock:: gnuradio.gr.repeat
+.. autooldblock:: gnuradio.gr.threshold_ff
+.. autooldblock:: gnuradio.gr.throttle
+.. autooldblock:: gnuradio.gr.channel_model
diff --git a/docs/sphinx/source/gr/modulation_blk.rst b/docs/sphinx/source/gr/modulation_blk.rst
index 7cc54d9dc5..1fff4614ca 100644
--- a/docs/sphinx/source/gr/modulation_blk.rst
+++ b/docs/sphinx/source/gr/modulation_blk.rst
@@ -1,6 +1,6 @@
gnuradio.gr: Modulation
=======================
-.. autoblock:: gnuradio.gr.cpfsk_bc
-.. autoblock:: gnuradio.gr.frequency_modulator_fc
-.. autoblock:: gnuradio.gr.phase_modulator_fc
+.. autooldblock:: gnuradio.gr.cpfsk_bc
+.. autooldblock:: gnuradio.gr.frequency_modulator_fc
+.. autooldblock:: gnuradio.gr.phase_modulator_fc
diff --git a/docs/sphinx/source/gr/sink_blk.rst b/docs/sphinx/source/gr/sink_blk.rst
index 8e5c7a4036..7608ff09b0 100644
--- a/docs/sphinx/source/gr/sink_blk.rst
+++ b/docs/sphinx/source/gr/sink_blk.rst
@@ -1,25 +1,25 @@
gnuradio.gr: Signal Sinks
=========================
-.. autoblock:: gnuradio.gr.bin_statistics_f
-.. autoblock:: gnuradio.gr.check_counting_s
-.. autoblock:: gnuradio.gr.check_lfsr_32k_s
-.. autoblock:: gnuradio.gr.framer_sink_1
-.. autoblock:: gnuradio.gr.null_sink
-.. autoblock:: gnuradio.gr.packet_sink
-.. autoblock:: gnuradio.gr.probe_avg_mag_sqrd_c
-.. autoblock:: gnuradio.gr.probe_avg_mag_sqrd_cf
-.. autoblock:: gnuradio.gr.probe_avg_mag_sqrd_f
-.. autoblock:: gnuradio.gr.probe_signal_f
-.. autoblock:: gnuradio.gr.vector_sink_b
-.. autoblock:: gnuradio.gr.vector_sink_c
-.. autoblock:: gnuradio.gr.vector_sink_f
-.. autoblock:: gnuradio.gr.vector_sink_i
-.. autoblock:: gnuradio.gr.vector_sink_s
-.. autoblock:: gnuradio.gr.file_descriptor_sink
-.. autoblock:: gnuradio.gr.file_sink
-.. autoblock:: gnuradio.gr.histo_sink_f
-.. autoblock:: gnuradio.gr.message_sink
-.. autoblock:: gnuradio.gr.oscope_sink_f
-.. autoblock:: gnuradio.gr.udp_sink
-.. autoblock:: gnuradio.gr.wavfile_sink
+.. autooldblock:: gnuradio.gr.bin_statistics_f
+.. autooldblock:: gnuradio.gr.check_counting_s
+.. autooldblock:: gnuradio.gr.check_lfsr_32k_s
+.. autooldblock:: gnuradio.gr.framer_sink_1
+.. autooldblock:: gnuradio.gr.null_sink
+.. autooldblock:: gnuradio.gr.packet_sink
+.. autooldblock:: gnuradio.gr.probe_avg_mag_sqrd_c
+.. autooldblock:: gnuradio.gr.probe_avg_mag_sqrd_cf
+.. autooldblock:: gnuradio.gr.probe_avg_mag_sqrd_f
+.. autooldblock:: gnuradio.gr.probe_signal_f
+.. autooldblock:: gnuradio.gr.vector_sink_b
+.. autooldblock:: gnuradio.gr.vector_sink_c
+.. autooldblock:: gnuradio.gr.vector_sink_f
+.. autooldblock:: gnuradio.gr.vector_sink_i
+.. autooldblock:: gnuradio.gr.vector_sink_s
+.. autooldblock:: gnuradio.gr.file_descriptor_sink
+.. autooldblock:: gnuradio.gr.file_sink
+.. autooldblock:: gnuradio.gr.histo_sink_f
+.. autooldblock:: gnuradio.gr.message_sink
+.. autooldblock:: gnuradio.gr.oscope_sink_f
+.. autooldblock:: gnuradio.gr.udp_sink
+.. autooldblock:: gnuradio.gr.wavfile_sink
diff --git a/docs/sphinx/source/gr/slicedice_blk.rst b/docs/sphinx/source/gr/slicedice_blk.rst
index 0bb5719ea6..e845627aad 100644
--- a/docs/sphinx/source/gr/slicedice_blk.rst
+++ b/docs/sphinx/source/gr/slicedice_blk.rst
@@ -1,14 +1,14 @@
gnuradio.gr: Slicing and Dicing Streams
=======================================
-.. autoblock:: gnuradio.gr.deinterleave
-.. autoblock:: gnuradio.gr.head
-.. autoblock:: gnuradio.gr.interleave
-.. autoblock:: gnuradio.gr.keep_one_in_n
-.. autoblock:: gnuradio.gr.skiphead
-.. autoblock:: gnuradio.gr.stream_to_streams
-.. autoblock:: gnuradio.gr.stream_to_vector
-.. autoblock:: gnuradio.gr.streams_to_stream
-.. autoblock:: gnuradio.gr.streams_to_vector
-.. autoblock:: gnuradio.gr.vector_to_stream
-.. autoblock:: gnuradio.gr.vector_to_streams
+.. autooldblock:: gnuradio.gr.deinterleave
+.. autooldblock:: gnuradio.gr.head
+.. autooldblock:: gnuradio.gr.interleave
+.. autooldblock:: gnuradio.gr.keep_one_in_n
+.. autooldblock:: gnuradio.gr.skiphead
+.. autooldblock:: gnuradio.gr.stream_to_streams
+.. autooldblock:: gnuradio.gr.stream_to_vector
+.. autooldblock:: gnuradio.gr.streams_to_stream
+.. autooldblock:: gnuradio.gr.streams_to_vector
+.. autooldblock:: gnuradio.gr.vector_to_stream
+.. autooldblock:: gnuradio.gr.vector_to_streams
diff --git a/docs/sphinx/source/gr/source_blk.rst b/docs/sphinx/source/gr/source_blk.rst
index e6e24e1b54..df873bcf74 100644
--- a/docs/sphinx/source/gr/source_blk.rst
+++ b/docs/sphinx/source/gr/source_blk.rst
@@ -1,26 +1,26 @@
gnuradio.gr: Signal Sources
===========================
-.. autoblock:: gnuradio.gr.glfsr_source_b
-.. autoblock:: gnuradio.gr.glfsr_source_f
-.. autoblock:: gnuradio.gr.lfsr_32k_source_s
-.. autoblock:: gnuradio.gr.null_source
-.. autoblock:: gnuradio.gr.noise_source_c
-.. autoblock:: gnuradio.gr.noise_source_f
-.. autoblock:: gnuradio.gr.noise_source_i
-.. autoblock:: gnuradio.gr.noise_source_s
-.. autoblock:: gnuradio.gr.sig_source_c
-.. autoblock:: gnuradio.gr.sig_source_f
-.. autoblock:: gnuradio.gr.sig_source_i
-.. autoblock:: gnuradio.gr.sig_source_s
-.. autoblock:: gnuradio.gr.vector_source_b
-.. autoblock:: gnuradio.gr.vector_source_c
-.. autoblock:: gnuradio.gr.vector_source_f
-.. autoblock:: gnuradio.gr.vector_source_i
-.. autoblock:: gnuradio.gr.vector_source_s
-.. autoblock:: gnuradio.gr.file_descriptor_source
-.. autoblock:: gnuradio.gr.file_source
-.. autoblock:: gnuradio.gr.message_source
-.. autoblock:: gnuradio.gr.udp_source
-.. autoblock:: gnuradio.gr.wavfile_source
+.. autooldblock:: gnuradio.gr.glfsr_source_b
+.. autooldblock:: gnuradio.gr.glfsr_source_f
+.. autooldblock:: gnuradio.gr.lfsr_32k_source_s
+.. autooldblock:: gnuradio.gr.null_source
+.. autooldblock:: gnuradio.gr.noise_source_c
+.. autooldblock:: gnuradio.gr.noise_source_f
+.. autooldblock:: gnuradio.gr.noise_source_i
+.. autooldblock:: gnuradio.gr.noise_source_s
+.. autooldblock:: gnuradio.gr.sig_source_c
+.. autooldblock:: gnuradio.gr.sig_source_f
+.. autooldblock:: gnuradio.gr.sig_source_i
+.. autooldblock:: gnuradio.gr.sig_source_s
+.. autooldblock:: gnuradio.gr.vector_source_b
+.. autooldblock:: gnuradio.gr.vector_source_c
+.. autooldblock:: gnuradio.gr.vector_source_f
+.. autooldblock:: gnuradio.gr.vector_source_i
+.. autooldblock:: gnuradio.gr.vector_source_s
+.. autooldblock:: gnuradio.gr.file_descriptor_source
+.. autooldblock:: gnuradio.gr.file_source
+.. autooldblock:: gnuradio.gr.message_source
+.. autooldblock:: gnuradio.gr.udp_source
+.. autooldblock:: gnuradio.gr.wavfile_source
diff --git a/docs/sphinx/source/gr/sync_blk.rst b/docs/sphinx/source/gr/sync_blk.rst
index bb2b839741..be9f908f73 100644
--- a/docs/sphinx/source/gr/sync_blk.rst
+++ b/docs/sphinx/source/gr/sync_blk.rst
@@ -1,9 +1,9 @@
gnuradio.gr: Synchronization
============================
-.. autoblock:: gnuradio.gr.pll_carriertracking_cc
-.. autoblock:: gnuradio.gr.pll_freqdet_cf
-.. autoblock:: gnuradio.gr.pll_refout_cc
-.. autoblock:: gnuradio.gr.pn_correlator_cc
-.. autoblock:: gnuradio.gr.simple_correlator
-.. autoblock:: gnuradio.gr.simple_framer
+.. autooldblock:: gnuradio.gr.pll_carriertracking_cc
+.. autooldblock:: gnuradio.gr.pll_freqdet_cf
+.. autooldblock:: gnuradio.gr.pll_refout_cc
+.. autooldblock:: gnuradio.gr.pn_correlator_cc
+.. autooldblock:: gnuradio.gr.simple_correlator
+.. autooldblock:: gnuradio.gr.simple_framer
diff --git a/docs/sphinx/source/index.rst b/docs/sphinx/source/index.rst
index 887271ce00..38d859aafd 100644
--- a/docs/sphinx/source/index.rst
+++ b/docs/sphinx/source/index.rst
@@ -15,6 +15,7 @@ Core Framework
gnuradio.audio
gnuradio.trellis
gnuradio.wavelet
+ gnuradio.fft
gnuradio.window
gnuradio.optfir
gnuradio.gr_unittest
@@ -32,6 +33,7 @@ Core Framework
gnuradio.optfir <optfir/index>
gnuradio.trellis <trellis/index>
gnuradio.wavelet <wavelet>
+ gnuradio.fft <fft>
gnuradio.window <window/index>
gnuradio.qtgui <qtgui/index>
gnuradio.wxgui <wxgui/index>
diff --git a/docs/sphinx/source/noaa.rst b/docs/sphinx/source/noaa.rst
index 06c7078130..65461f99b8 100644
--- a/docs/sphinx/source/noaa.rst
+++ b/docs/sphinx/source/noaa.rst
@@ -3,6 +3,6 @@ gnuradio.noaa
.. automodule:: gnuradio.noaa
-.. autoblock:: gnuradio.noaa.hrpt_decoder
-.. autoblock:: gnuradio.noaa.hrpt_deframer
-.. autoblock:: gnuradio.noaa.hrpt_pll_cf
+.. autooldblock:: gnuradio.noaa.hrpt_decoder
+.. autooldblock:: gnuradio.noaa.hrpt_deframer
+.. autooldblock:: gnuradio.noaa.hrpt_pll_cf
diff --git a/docs/sphinx/source/pager/blks.rst b/docs/sphinx/source/pager/blks.rst
index 9b5a2ca70d..a36103d1fa 100644
--- a/docs/sphinx/source/pager/blks.rst
+++ b/docs/sphinx/source/pager/blks.rst
@@ -1,9 +1,9 @@
gnuradio.pager: Signal Processing Blocks
========================================
-.. autoblock:: gnuradio.pager.flex_deinterleave
+.. autooldblock:: gnuradio.pager.flex_deinterleave
.. autopyblock:: gnuradio.pager.flex_demod
-.. autoblock:: gnuradio.pager.flex_frame
-.. autoblock:: gnuradio.pager.flex_parse
-.. autoblock:: gnuradio.pager.flex_sync
-.. autoblock:: gnuradio.pager.slicer_fb
+.. autooldblock:: gnuradio.pager.flex_frame
+.. autooldblock:: gnuradio.pager.flex_parse
+.. autooldblock:: gnuradio.pager.flex_sync
+.. autooldblock:: gnuradio.pager.slicer_fb
diff --git a/docs/sphinx/source/qtgui/index.rst b/docs/sphinx/source/qtgui/index.rst
index c6311d381a..83bdedca89 100644
--- a/docs/sphinx/source/qtgui/index.rst
+++ b/docs/sphinx/source/qtgui/index.rst
@@ -3,7 +3,7 @@ gnuradio.qtgui
.. automodule:: gnuradio.qtgui
-.. autoblock:: gnuradio.qtgui.sink_c
-.. autoblock:: gnuradio.qtgui.sink_f
-.. autoblock:: gnuradio.qtgui.time_sink_c
-.. autoblock:: gnuradio.qtgui.time_sink_f
+.. autooldblock:: gnuradio.qtgui.sink_c
+.. autooldblock:: gnuradio.qtgui.sink_f
+.. autooldblock:: gnuradio.qtgui.time_sink_c
+.. autooldblock:: gnuradio.qtgui.time_sink_f
diff --git a/docs/sphinx/source/trellis/blks.rst b/docs/sphinx/source/trellis/blks.rst
index a2eda07d61..d82319bad6 100644
--- a/docs/sphinx/source/trellis/blks.rst
+++ b/docs/sphinx/source/trellis/blks.rst
@@ -1,62 +1,62 @@
gnuradio.trellis: Signal Processing Blocks
==========================================
-.. autoblock:: gnuradio.trellis.constellation_metrics_cf
-.. autoblock:: gnuradio.trellis.encoder_bb
-.. autoblock:: gnuradio.trellis.encoder_bi
-.. autoblock:: gnuradio.trellis.encoder_bs
-.. autoblock:: gnuradio.trellis.encoder_ii
-.. autoblock:: gnuradio.trellis.encoder_si
-.. autoblock:: gnuradio.trellis.encoder_ss
-.. autoblock:: gnuradio.trellis.metrics_c
-.. autoblock:: gnuradio.trellis.metrics_f
-.. autoblock:: gnuradio.trellis.metrics_i
-.. autoblock:: gnuradio.trellis.metrics_s
-.. autoblock:: gnuradio.trellis.pccc_decoder_b
-.. autoblock:: gnuradio.trellis.pccc_decoder_combined_cb
-.. autoblock:: gnuradio.trellis.pccc_decoder_combined_ci
-.. autoblock:: gnuradio.trellis.pccc_decoder_combined_cs
-.. autoblock:: gnuradio.trellis.pccc_decoder_combined_fb
-.. autoblock:: gnuradio.trellis.pccc_decoder_combined_fi
-.. autoblock:: gnuradio.trellis.pccc_decoder_combined_fs
-.. autoblock:: gnuradio.trellis.pccc_decoder_i
-.. autoblock:: gnuradio.trellis.pccc_decoder_s
-.. autoblock:: gnuradio.trellis.pccc_encoder_bb
-.. autoblock:: gnuradio.trellis.pccc_encoder_bi
-.. autoblock:: gnuradio.trellis.pccc_encoder_bs
-.. autoblock:: gnuradio.trellis.pccc_encoder_ii
-.. autoblock:: gnuradio.trellis.pccc_encoder_si
-.. autoblock:: gnuradio.trellis.pccc_encoder_ss
-.. autoblock:: gnuradio.trellis.permutation
-.. autoblock:: gnuradio.trellis.sccc_decoder_b
-.. autoblock:: gnuradio.trellis.sccc_decoder_combined_cb
-.. autoblock:: gnuradio.trellis.sccc_decoder_combined_ci
-.. autoblock:: gnuradio.trellis.sccc_decoder_combined_cs
-.. autoblock:: gnuradio.trellis.sccc_decoder_combined_fb
-.. autoblock:: gnuradio.trellis.sccc_decoder_combined_fi
-.. autoblock:: gnuradio.trellis.sccc_decoder_combined_fs
-.. autoblock:: gnuradio.trellis.sccc_decoder_i
-.. autoblock:: gnuradio.trellis.sccc_decoder_s
-.. autoblock:: gnuradio.trellis.sccc_encoder_bb
-.. autoblock:: gnuradio.trellis.sccc_encoder_bi
-.. autoblock:: gnuradio.trellis.sccc_encoder_bs
-.. autoblock:: gnuradio.trellis.sccc_encoder_ii
-.. autoblock:: gnuradio.trellis.sccc_encoder_si
-.. autoblock:: gnuradio.trellis.sccc_encoder_ss
-.. autoblock:: gnuradio.trellis.siso_combined_f
-.. autoblock:: gnuradio.trellis.siso_f
-.. autoblock:: gnuradio.trellis.viterbi_b
-.. autoblock:: gnuradio.trellis.viterbi_combined_cb
-.. autoblock:: gnuradio.trellis.viterbi_combined_ci
-.. autoblock:: gnuradio.trellis.viterbi_combined_cs
-.. autoblock:: gnuradio.trellis.viterbi_combined_fb
-.. autoblock:: gnuradio.trellis.viterbi_combined_fi
-.. autoblock:: gnuradio.trellis.viterbi_combined_fs
-.. autoblock:: gnuradio.trellis.viterbi_combined_ib
-.. autoblock:: gnuradio.trellis.viterbi_combined_ii
-.. autoblock:: gnuradio.trellis.viterbi_combined_is
-.. autoblock:: gnuradio.trellis.viterbi_combined_sb
-.. autoblock:: gnuradio.trellis.viterbi_combined_si
-.. autoblock:: gnuradio.trellis.viterbi_combined_ss
-.. autoblock:: gnuradio.trellis.viterbi_i
-.. autoblock:: gnuradio.trellis.viterbi_s
+.. autooldblock:: gnuradio.trellis.constellation_metrics_cf
+.. autooldblock:: gnuradio.trellis.encoder_bb
+.. autooldblock:: gnuradio.trellis.encoder_bi
+.. autooldblock:: gnuradio.trellis.encoder_bs
+.. autooldblock:: gnuradio.trellis.encoder_ii
+.. autooldblock:: gnuradio.trellis.encoder_si
+.. autooldblock:: gnuradio.trellis.encoder_ss
+.. autooldblock:: gnuradio.trellis.metrics_c
+.. autooldblock:: gnuradio.trellis.metrics_f
+.. autooldblock:: gnuradio.trellis.metrics_i
+.. autooldblock:: gnuradio.trellis.metrics_s
+.. autooldblock:: gnuradio.trellis.pccc_decoder_b
+.. autooldblock:: gnuradio.trellis.pccc_decoder_combined_cb
+.. autooldblock:: gnuradio.trellis.pccc_decoder_combined_ci
+.. autooldblock:: gnuradio.trellis.pccc_decoder_combined_cs
+.. autooldblock:: gnuradio.trellis.pccc_decoder_combined_fb
+.. autooldblock:: gnuradio.trellis.pccc_decoder_combined_fi
+.. autooldblock:: gnuradio.trellis.pccc_decoder_combined_fs
+.. autooldblock:: gnuradio.trellis.pccc_decoder_i
+.. autooldblock:: gnuradio.trellis.pccc_decoder_s
+.. autooldblock:: gnuradio.trellis.pccc_encoder_bb
+.. autooldblock:: gnuradio.trellis.pccc_encoder_bi
+.. autooldblock:: gnuradio.trellis.pccc_encoder_bs
+.. autooldblock:: gnuradio.trellis.pccc_encoder_ii
+.. autooldblock:: gnuradio.trellis.pccc_encoder_si
+.. autooldblock:: gnuradio.trellis.pccc_encoder_ss
+.. autooldblock:: gnuradio.trellis.permutation
+.. autooldblock:: gnuradio.trellis.sccc_decoder_b
+.. autooldblock:: gnuradio.trellis.sccc_decoder_combined_cb
+.. autooldblock:: gnuradio.trellis.sccc_decoder_combined_ci
+.. autooldblock:: gnuradio.trellis.sccc_decoder_combined_cs
+.. autooldblock:: gnuradio.trellis.sccc_decoder_combined_fb
+.. autooldblock:: gnuradio.trellis.sccc_decoder_combined_fi
+.. autooldblock:: gnuradio.trellis.sccc_decoder_combined_fs
+.. autooldblock:: gnuradio.trellis.sccc_decoder_i
+.. autooldblock:: gnuradio.trellis.sccc_decoder_s
+.. autooldblock:: gnuradio.trellis.sccc_encoder_bb
+.. autooldblock:: gnuradio.trellis.sccc_encoder_bi
+.. autooldblock:: gnuradio.trellis.sccc_encoder_bs
+.. autooldblock:: gnuradio.trellis.sccc_encoder_ii
+.. autooldblock:: gnuradio.trellis.sccc_encoder_si
+.. autooldblock:: gnuradio.trellis.sccc_encoder_ss
+.. autooldblock:: gnuradio.trellis.siso_combined_f
+.. autooldblock:: gnuradio.trellis.siso_f
+.. autooldblock:: gnuradio.trellis.viterbi_b
+.. autooldblock:: gnuradio.trellis.viterbi_combined_cb
+.. autooldblock:: gnuradio.trellis.viterbi_combined_ci
+.. autooldblock:: gnuradio.trellis.viterbi_combined_cs
+.. autooldblock:: gnuradio.trellis.viterbi_combined_fb
+.. autooldblock:: gnuradio.trellis.viterbi_combined_fi
+.. autooldblock:: gnuradio.trellis.viterbi_combined_fs
+.. autooldblock:: gnuradio.trellis.viterbi_combined_ib
+.. autooldblock:: gnuradio.trellis.viterbi_combined_ii
+.. autooldblock:: gnuradio.trellis.viterbi_combined_is
+.. autooldblock:: gnuradio.trellis.viterbi_combined_sb
+.. autooldblock:: gnuradio.trellis.viterbi_combined_si
+.. autooldblock:: gnuradio.trellis.viterbi_combined_ss
+.. autooldblock:: gnuradio.trellis.viterbi_i
+.. autooldblock:: gnuradio.trellis.viterbi_s
diff --git a/docs/sphinx/source/video_sdl.rst b/docs/sphinx/source/video_sdl.rst
index e4fc5acac3..6be88d788c 100644
--- a/docs/sphinx/source/video_sdl.rst
+++ b/docs/sphinx/source/video_sdl.rst
@@ -3,5 +3,5 @@ gnuradio.video_sdl
.. automodule:: gnuradio.video_sdl
-.. autoblock:: gnuradio.video_sdl.sink_s
-.. autoblock:: gnuradio.video_sdl.sink_uc
+.. autooldblock:: gnuradio.video_sdl.sink_s
+.. autooldblock:: gnuradio.video_sdl.sink_uc
diff --git a/docs/sphinx/source/vocoder/blks.rst b/docs/sphinx/source/vocoder/blks.rst
index ea20bc44be..34eda9d250 100644
--- a/docs/sphinx/source/vocoder/blks.rst
+++ b/docs/sphinx/source/vocoder/blks.rst
@@ -1,19 +1,19 @@
gnuradio.vocoder
================
-.. autoblock:: gnuradio.vocoder.alaw_decode_bs
-.. autoblock:: gnuradio.vocoder.alaw_encode_sb
-.. autoblock:: gnuradio.vocoder.codec2_decode_ps
-.. autoblock:: gnuradio.vocoder.codec2_encode_sp
-.. autoblock:: gnuradio.vocoder.cvsd_decode_bs
-.. autoblock:: gnuradio.vocoder.cvsd_encode_sb
-.. autoblock:: gnuradio.vocoder.g721_decode_bs
-.. autoblock:: gnuradio.vocoder.g721_encode_sb
-.. autoblock:: gnuradio.vocoder.g723_24_decode_bs
-.. autoblock:: gnuradio.vocoder.g723_24_encode_sb
-.. autoblock:: gnuradio.vocoder.g723_40_decode_bs
-.. autoblock:: gnuradio.vocoder.g723_40_encode_sb
-.. autoblock:: gnuradio.vocoder.gsm_fr_decode_ps
-.. autoblock:: gnuradio.vocoder.gsm_fr_encode_sp
-.. autoblock:: gnuradio.vocoder.ulaw_decode_bs
-.. autoblock:: gnuradio.vocoder.ulaw_encode_sb
+.. autooldblock:: gnuradio.vocoder.alaw_decode_bs
+.. autooldblock:: gnuradio.vocoder.alaw_encode_sb
+.. autooldblock:: gnuradio.vocoder.codec2_decode_ps
+.. autooldblock:: gnuradio.vocoder.codec2_encode_sp
+.. autooldblock:: gnuradio.vocoder.cvsd_decode_bs
+.. autooldblock:: gnuradio.vocoder.cvsd_encode_sb
+.. autooldblock:: gnuradio.vocoder.g721_decode_bs
+.. autooldblock:: gnuradio.vocoder.g721_encode_sb
+.. autooldblock:: gnuradio.vocoder.g723_24_decode_bs
+.. autooldblock:: gnuradio.vocoder.g723_24_encode_sb
+.. autooldblock:: gnuradio.vocoder.g723_40_decode_bs
+.. autooldblock:: gnuradio.vocoder.g723_40_encode_sb
+.. autooldblock:: gnuradio.vocoder.gsm_fr_decode_ps
+.. autooldblock:: gnuradio.vocoder.gsm_fr_encode_sp
+.. autooldblock:: gnuradio.vocoder.ulaw_decode_bs
+.. autooldblock:: gnuradio.vocoder.ulaw_encode_sb
diff --git a/docs/sphinx/source/wavelet.rst b/docs/sphinx/source/wavelet.rst
index 679bab70c0..5236c4dbb2 100644
--- a/docs/sphinx/source/wavelet.rst
+++ b/docs/sphinx/source/wavelet.rst
@@ -3,6 +3,6 @@ gnuradio.wavelet
.. automodule:: gnuradio.wavelet
-.. autoblock:: gnuradio.wavelet.squash_ff
-.. autoblock:: gnuradio.wavelet.wavelet_ff
-.. autoblock:: gnuradio.wavelet.wvps_ff
+.. autooldblock:: gnuradio.wavelet.squash_ff
+.. autooldblock:: gnuradio.wavelet.wavelet_ff
+.. autooldblock:: gnuradio.wavelet.wvps_ff
diff --git a/gnuradio-core/CMakeLists.txt b/gnuradio-core/CMakeLists.txt
index 0227108446..4e76b3c5a6 100644
--- a/gnuradio-core/CMakeLists.txt
+++ b/gnuradio-core/CMakeLists.txt
@@ -64,6 +64,7 @@ GR_SET_GLOBAL(GNURADIO_CORE_INCLUDE_DIRS
GR_SET_GLOBAL(GNURADIO_CORE_SWIG_INCLUDE_DIRS
${CMAKE_SOURCE_DIR}/gruel/src/swig
+ ${CMAKE_BINARY_DIR}/gruel/src/swig/
${CMAKE_CURRENT_SOURCE_DIR}/src/lib/swig
${GNURADIO_CORE_INCLUDE_DIRS}
)
@@ -109,7 +110,7 @@ CPACK_COMPONENT("core_swig"
install(
FILES gnuradio-core.conf
- DESTINATION ${GR_PKG_CONF_DIR}
+ DESTINATION ${GR_PREFSDIR}
COMPONENT "core_runtime"
)
diff --git a/gnuradio-core/src/lib/general/CMakeLists.txt b/gnuradio-core/src/lib/general/CMakeLists.txt
index 207d85c4c4..082601d5e1 100644
--- a/gnuradio-core/src/lib/general/CMakeLists.txt
+++ b/gnuradio-core/src/lib/general/CMakeLists.txt
@@ -48,9 +48,6 @@ message(STATUS "Loading build date ${BUILD_DATE} into gr_constants...")
message(STATUS "Loading version ${VERSION} into gr_constants...")
-file(TO_NATIVE_PATH "${CMAKE_INSTALL_PREFIX}/${GR_CONF_DIR}" SYSCONFDIR)
-file(TO_NATIVE_PATH "${CMAKE_INSTALL_PREFIX}/${GR_PKG_CONF_DIR}" GR_PREFSDIR)
-
#double escape for windows backslash path separators
string(REPLACE "\\" "\\\\" prefix ${prefix})
string(REPLACE "\\" "\\\\" SYSCONFDIR ${SYSCONFDIR})
@@ -84,7 +81,6 @@ list(APPEND gnuradio_core_sources
${CMAKE_CURRENT_SOURCE_DIR}/gri_float_to_int.cc
${CMAKE_CURRENT_SOURCE_DIR}/gri_float_to_short.cc
${CMAKE_CURRENT_SOURCE_DIR}/gri_float_to_uchar.cc
- ${CMAKE_CURRENT_SOURCE_DIR}/gri_glfsr.cc
${CMAKE_CURRENT_SOURCE_DIR}/gri_interleaved_short_to_complex.cc
${CMAKE_CURRENT_SOURCE_DIR}/gri_int_to_float.cc
${CMAKE_CURRENT_SOURCE_DIR}/gri_short_to_float.cc
@@ -104,7 +100,6 @@ list(APPEND test_gnuradio_core_sources
${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_fxpt_nco.cc
${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_fxpt_vco.cc
${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_math.cc
- ${CMAKE_CURRENT_SOURCE_DIR}/qa_gri_lfsr.cc
)
########################################################################
@@ -143,7 +138,6 @@ install(FILES
${CMAKE_CURRENT_SOURCE_DIR}/gri_float_to_short.h
${CMAKE_CURRENT_SOURCE_DIR}/gri_float_to_uchar.h
${CMAKE_CURRENT_SOURCE_DIR}/gri_lfsr.h
- ${CMAKE_CURRENT_SOURCE_DIR}/gri_glfsr.h
${CMAKE_CURRENT_SOURCE_DIR}/gri_interleaved_short_to_complex.h
${CMAKE_CURRENT_SOURCE_DIR}/gri_lfsr_15_1_0.h
${CMAKE_CURRENT_SOURCE_DIR}/gri_lfsr_32k.h
@@ -179,14 +173,12 @@ endif(ENABLE_PYTHON)
set(gr_core_general_triple_threats
complex_vec_test
gr_add_ff
- gr_additive_scrambler_bb
gr_agc_cc
gr_agc_ff
gr_agc2_cc
gr_agc2_ff
gr_align_on_samplenumbers_ss
gr_bin_statistics_f
- gr_bytes_to_syms
gr_char_to_float
gr_char_to_short
gr_check_counting_s
@@ -199,9 +191,6 @@ set(gr_core_general_triple_threats
gr_cpm
gr_ctcss_squelch_ff
gr_decode_ccsds_27_fb
- gr_diff_decoder_bb
- gr_diff_encoder_bb
- gr_diff_phasor_cc
gr_dpll_bb
gr_deinterleave
gr_delay
@@ -219,18 +208,15 @@ set(gr_core_general_triple_threats
gr_float_to_uchar
gr_fmdet_cf
gr_frequency_modulator_fc
- gr_framer_sink_1
- gr_glfsr_source_b
- gr_glfsr_source_f
gr_head
gr_int_to_float
gr_interleave
gr_interleaved_short_to_complex
gr_iqcomp_cc
gr_keep_one_in_n
+ gr_keep_m_in_n
gr_kludge_copy
gr_lfsr_32k_source_s
- gr_map_bb
gr_multiply_cc
gr_multiply_ff
gr_multiply_const_cc
@@ -241,13 +227,11 @@ set(gr_core_general_triple_threats
gr_null_sink
gr_null_source
gr_pa_2x2_phase_combiner
- gr_packet_sink
gr_peak_detector2_fb
gr_phase_modulator_fc
gr_pll_carriertracking_cc
gr_pll_freqdet_cf
gr_pll_refout_cc
- gr_pn_correlator_cc
gr_prefs
gr_probe_avg_mag_sqrd_c
gr_probe_avg_mag_sqrd_cf
@@ -264,7 +248,6 @@ set(gr_core_general_triple_threats
gr_short_to_float
gr_short_to_char
gr_simple_correlator
- gr_simple_framer
gr_simple_squelch_cc
gr_skiphead
gr_squelch_base_cc
@@ -281,16 +264,16 @@ set(gr_core_general_triple_threats
gr_transcendental
gr_uchar_to_float
gr_vco_f
+ gr_vector_map
gr_vector_to_stream
gr_vector_to_streams
gr_unpack_k_bits_bb
- gr_descrambler_bb
- gr_scrambler_bb
- gr_probe_density_b
+ gr_pack_k_bits_bb
gr_annotator_alltoall
gr_annotator_1to1
+ gr_annotator_raw
gr_burst_tagger
- gr_correlate_access_code_tag_bb
+ gr_tag_debug
)
foreach(file_tt ${gr_core_general_triple_threats})
diff --git a/gnuradio-core/src/lib/general/general.i b/gnuradio-core/src/lib/general/general.i
index cd8c279c92..b4ddee29ce 100644
--- a/gnuradio-core/src/lib/general/general.i
+++ b/gnuradio-core/src/lib/general/general.i
@@ -37,6 +37,7 @@
#include <gr_stream_to_vector.h>
#include <gr_vector_to_stream.h>
#include <gr_keep_one_in_n.h>
+#include <gr_keep_m_in_n.h>
#include <gr_fft_vcc.h>
#include <gr_fft_vfc.h>
#include <gr_float_to_int.h>
@@ -51,9 +52,7 @@
#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>
@@ -82,13 +81,11 @@
#include <gr_conjugate_cc.h>
#include <gr_vco_f.h>
#include <gr_threshold_ff.h>
-#include <gr_packet_sink.h>
#include <gr_dpll_bb.h>
#include <gr_fmdet_cf.h>
#include <gr_pll_freqdet_cf.h>
#include <gr_pll_refout_cc.h>
#include <gr_pll_carriertracking_cc.h>
-#include <gr_pn_correlator_cc.h>
#include <gr_probe_avg_mag_sqrd_c.h>
#include <gr_probe_avg_mag_sqrd_cf.h>
#include <gr_probe_avg_mag_sqrd_f.h>
@@ -100,11 +97,7 @@
#include <gr_test_types.h>
#include <gr_test.h>
#include <gr_unpack_k_bits_bb.h>
-#include <gr_diff_phasor_cc.h>
-#include <gr_diff_encoder_bb.h>
-#include <gr_diff_decoder_bb.h>
-#include <gr_framer_sink_1.h>
-#include <gr_map_bb.h>
+#include <gr_pack_k_bits_bb.h>
#include <gr_multiply_cc.h>
#include <gr_multiply_ff.h>
#include <gr_multiply_const_cc.h>
@@ -116,27 +109,23 @@
#include <gr_ctcss_squelch_ff.h>
#include <gr_feedforward_agc_cc.h>
#include <gr_bin_statistics_f.h>
-#include <gr_glfsr_source_b.h>
-#include <gr_glfsr_source_f.h>
#include <gr_peak_detector2_fb.h>
#include <gr_repeat.h>
#include <gr_cpfsk_bc.h>
#include <gr_encode_ccsds_27_bb.h>
#include <gr_decode_ccsds_27_fb.h>
-#include <gr_descrambler_bb.h>
-#include <gr_scrambler_bb.h>
-#include <gr_probe_density_b.h>
#include <gr_rail_ff.h>
#include <gr_stretch_ff.h>
#include <gr_copy.h>
-#include <gr_additive_scrambler_bb.h>
#include <complex_vec_test.h>
#include <gr_annotator_alltoall.h>
#include <gr_annotator_1to1.h>
+#include <gr_annotator_raw.h>
#include <gr_burst_tagger.h>
#include <gr_cpm.h>
-#include <gr_correlate_access_code_tag_bb.h>
+#include <gr_vector_map.h>
#include <gr_add_ff.h>
+#include <gr_tag_debug.h>
%}
%include "gri_control_loop.i"
@@ -154,6 +143,7 @@
%include "gr_stream_to_vector.i"
%include "gr_vector_to_stream.i"
%include "gr_keep_one_in_n.i"
+%include "gr_keep_m_in_n.i"
%include "gr_fft_vcc.i"
%include "gr_fft_vfc.i"
%include "gr_float_to_int.i"
@@ -168,9 +158,7 @@
%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"
@@ -199,13 +187,11 @@
%include "gr_conjugate_cc.i"
%include "gr_vco_f.i"
%include "gr_threshold_ff.i"
-%include "gr_packet_sink.i"
%include "gr_dpll_bb.i"
%include "gr_fmdet_cf.i"
%include "gr_pll_freqdet_cf.i"
%include "gr_pll_refout_cc.i"
%include "gr_pll_carriertracking_cc.i"
-%include "gr_pn_correlator_cc.i"
%include "gr_probe_avg_mag_sqrd_c.i"
%include "gr_probe_avg_mag_sqrd_cf.i"
%include "gr_probe_avg_mag_sqrd_f.i"
@@ -217,11 +203,7 @@
%include "gr_test_types.h"
%include "gr_test.i"
%include "gr_unpack_k_bits_bb.i"
-%include "gr_diff_phasor_cc.i"
-%include "gr_diff_encoder_bb.i"
-%include "gr_diff_decoder_bb.i"
-%include "gr_framer_sink_1.i"
-%include "gr_map_bb.i"
+%include "gr_pack_k_bits_bb.i"
%include "gr_multiply_cc.i"
%include "gr_multiply_ff.i"
%include "gr_multiply_const_cc.i"
@@ -233,24 +215,20 @@
%include "gr_ctcss_squelch_ff.i"
%include "gr_feedforward_agc_cc.i"
%include "gr_bin_statistics_f.i"
-%include "gr_glfsr_source_b.i"
-%include "gr_glfsr_source_f.i"
%include "gr_peak_detector2_fb.i"
%include "gr_repeat.i"
%include "gr_cpfsk_bc.i"
%include "gr_encode_ccsds_27_bb.i"
%include "gr_decode_ccsds_27_fb.i"
-%include "gr_descrambler_bb.i"
-%include "gr_scrambler_bb.i"
-%include "gr_probe_density_b.i"
%include "gr_rail_ff.i"
%include "gr_stretch_ff.i"
%include "gr_copy.i"
-%include "gr_additive_scrambler_bb.i"
%include "complex_vec_test.i"
%include "gr_annotator_alltoall.i"
%include "gr_annotator_1to1.i"
+%include "gr_annotator_raw.i"
%include "gr_burst_tagger.i"
%include "gr_cpm.i"
-%include "gr_correlate_access_code_tag_bb.i"
+%include "gr_vector_map.i"
%include "gr_add_ff.i"
+%include "gr_tag_debug.i"
diff --git a/gnuradio-core/src/lib/general/general_generated.i b/gnuradio-core/src/lib/general/general_generated.i
index 89b7e1776e..43828e7f71 100644
--- a/gnuradio-core/src/lib/general/general_generated.i
+++ b/gnuradio-core/src/lib/general/general_generated.i
@@ -18,12 +18,6 @@
#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>
@@ -100,12 +94,6 @@
%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>
diff --git a/gnuradio-core/src/lib/general/gr_add_ff.cc b/gnuradio-core/src/lib/general/gr_add_ff.cc
index 2e45673d3b..5f6676bb7b 100644
--- a/gnuradio-core/src/lib/general/gr_add_ff.cc
+++ b/gnuradio-core/src/lib/general/gr_add_ff.cc
@@ -42,7 +42,7 @@ gr_add_ff::gr_add_ff (size_t vlen)
{
const int alignment_multiple =
volk_get_alignment() / sizeof(float);
- set_alignment(alignment_multiple);
+ set_alignment(std::max(1,alignment_multiple));
}
int
diff --git a/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.cc b/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.cc
deleted file mode 100644
index 35cbb9572f..0000000000
--- a/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008,2010 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gr_additive_scrambler_bb.h>
-#include <gr_io_signature.h>
-
-gr_additive_scrambler_bb_sptr
-gr_make_additive_scrambler_bb(int mask, int seed, int len, int count)
-{
- return gnuradio::get_initial_sptr(new gr_additive_scrambler_bb(mask, seed, len, count));
-}
-
-gr_additive_scrambler_bb::gr_additive_scrambler_bb(int mask, int seed, int len, int count)
- : gr_sync_block("additive_scrambler_bb",
- gr_make_io_signature (1, 1, sizeof (unsigned char)),
- gr_make_io_signature (1, 1, sizeof (unsigned char))),
- d_lfsr(mask, seed, len),
- d_count(count),
- d_bits(0)
-{
-}
-
-int
-gr_additive_scrambler_bb::work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- const unsigned char *in = (const unsigned char *) input_items[0];
- unsigned char *out = (unsigned char *) output_items[0];
-
- for (int i = 0; i < noutput_items; i++) {
- out[i] = in[i]^d_lfsr.next_bit();
- if (d_count > 0) {
- if (++d_bits == d_count) {
- d_lfsr.reset();
- d_bits = 0;
- }
- }
- }
-
- return noutput_items;
-}
diff --git a/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.h b/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.h
deleted file mode 100644
index 1c336306d6..0000000000
--- a/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008,2010 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-#ifndef INCLUDED_GR_ADDITIVE_SCRAMBLER_BB_H
-#define INCLUDED_GR_ADDITIVE_SCRAMBLER_BB_H
-
-#include <gr_core_api.h>
-#include <gr_sync_block.h>
-#include "gri_lfsr.h"
-
-class gr_additive_scrambler_bb;
-typedef boost::shared_ptr<gr_additive_scrambler_bb> gr_additive_scrambler_bb_sptr;
-
-GR_CORE_API gr_additive_scrambler_bb_sptr gr_make_additive_scrambler_bb(int mask, int seed, int len, int count=0);
-
-/*!
- * Scramble an input stream using an LFSR. This block works on the LSB only
- * of the input data stream, i.e., on an "unpacked binary" stream, and
- * produces the same format on its output.
- *
- * \param mask Polynomial mask for LFSR
- * \param seed Initial shift register contents
- * \param len Shift register length
- * \param count Number of bits after which shift register is reset, 0=never
- *
- * The scrambler works by XORing the incoming bit stream by the output of
- * the LFSR. Optionally, after 'count' bits have been processed, the shift
- * register is reset to the seed value. This allows processing fixed length
- * vectors of samples.
- *
- * \ingroup coding_blk
- */
-
-class GR_CORE_API gr_additive_scrambler_bb : public gr_sync_block
-{
- friend GR_CORE_API gr_additive_scrambler_bb_sptr gr_make_additive_scrambler_bb(int mask, int seed, int len, int count);
-
- gri_lfsr d_lfsr;
- int d_count;
- int d_bits;
-
- gr_additive_scrambler_bb(int mask, int seed, int len, int count);
-
-public:
- int work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-};
-
-#endif /* INCLUDED_GR_ADDITIVE_SCRAMBLER_BB_H */
diff --git a/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.i b/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.i
deleted file mode 100644
index acf9e8c47e..0000000000
--- a/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.i
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008,2010 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-GR_SWIG_BLOCK_MAGIC(gr,additive_scrambler_bb);
-
-gr_additive_scrambler_bb_sptr gr_make_additive_scrambler_bb(int mask, int seed, int len, int count=0);
-
-class gr_additive_scrambler_bb : public gr_sync_block
-{
-private:
- gr_additive_scrambler_bb(int mask, int seed, int len, int count);
-};
diff --git a/gnuradio-core/src/lib/general/gr_annotator_raw.cc b/gnuradio-core/src/lib/general/gr_annotator_raw.cc
new file mode 100644
index 0000000000..e1ae73efb6
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_annotator_raw.cc
@@ -0,0 +1,106 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_annotator_raw.h>
+#include <gr_io_signature.h>
+#include <string.h>
+#include <iostream>
+#include <iomanip>
+#include <stdexcept>
+
+using namespace pmt;
+
+gr_annotator_raw_sptr
+gr_make_annotator_raw(size_t sizeof_stream_item)
+{
+ return gnuradio::get_initial_sptr(new gr_annotator_raw
+ (sizeof_stream_item));
+}
+
+gr_annotator_raw::gr_annotator_raw(size_t sizeof_stream_item)
+ : gr_sync_block("annotator_raw",
+ gr_make_io_signature(1, 1, sizeof_stream_item),
+ gr_make_io_signature(1, 1, sizeof_stream_item)),
+ d_itemsize(sizeof_stream_item)
+{
+ set_tag_propagation_policy(TPP_ONE_TO_ONE);
+ set_relative_rate(1.0);
+}
+
+void gr_annotator_raw::add_tag(uint64_t offset, pmt_t key, pmt_t val)
+{
+ gruel::scoped_lock l(d_mutex);
+
+ gr_tag_t tag;
+ tag.srcid = pmt::pmt_intern(d_name);
+ tag.key = key;
+ tag.value = val;
+ tag.offset = offset;
+
+ // add our new tag
+ d_queued_tags.push_back(tag);
+ // make sure our tags are in offset order
+ std::sort(d_queued_tags.begin(), d_queued_tags.end(),
+ gr_tag_t::offset_compare);
+ // make sure we are not adding an item in the past!
+ if(tag.offset > nitems_read(0)) {
+ throw std::runtime_error("gr_annotator_raw::add_tag: item added too far in the past\n.");
+ }
+}
+
+gr_annotator_raw::~gr_annotator_raw()
+{
+}
+
+int
+gr_annotator_raw::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ gruel::scoped_lock l(d_mutex);
+
+ const char *in = (const char*)input_items[0];
+ char *out = (char*)output_items[0];
+
+ uint64_t start_N = nitems_read(0);
+ uint64_t end_N = start_N + (uint64_t)(noutput_items);
+
+ // locate queued tags that fall in this range and insert them when appropriate
+ std::vector<gr_tag_t>::iterator i = d_queued_tags.begin();
+ while( i != d_queued_tags.end() ) {
+ if( (*i).offset >= start_N && (*i).offset < end_N) {
+ add_item_tag(0, (*i).offset,(*i).key, (*i).value, (*i).srcid);
+ i = d_queued_tags.erase(i);
+ }
+ else {
+ break;
+ }
+ }
+
+ // copy data across
+ memcpy(out, in, noutput_items*d_itemsize);
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_annotator_raw.h b/gnuradio-core/src/lib/general/gr_annotator_raw.h
new file mode 100644
index 0000000000..8a6c3f6c02
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_annotator_raw.h
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_ANNOTATOR_RAW_H
+#define INCLUDED_GR_ANNOTATOR_RAW_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gruel/pmt.h>
+#include <gruel/thread.h>
+
+class gr_annotator_raw;
+typedef boost::shared_ptr<gr_annotator_raw> gr_annotator_raw_sptr;
+
+// public constructor
+GR_CORE_API gr_annotator_raw_sptr
+gr_make_annotator_raw(size_t sizeof_stream_item);
+
+/*!
+ * \brief raw stream annotator testing block.
+ *
+ * This block creates arbitrary tags to be sent downstream
+ * blocks to be sent are set manually via accessor methods and are sent only once.
+ *
+ * This block is intended for testing of tag related blocks
+ */
+class GR_CORE_API gr_annotator_raw : public gr_sync_block
+{
+ public:
+ ~gr_annotator_raw();
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ // insert a tag to be added
+ void add_tag(uint64_t offset, pmt::pmt_t key, pmt::pmt_t val);
+
+protected:
+ gr_annotator_raw(size_t sizeof_stream_item);
+
+ private:
+ size_t d_itemsize;
+ std::vector<gr_tag_t> d_queued_tags;
+ gruel::mutex d_mutex;
+
+ friend GR_CORE_API gr_annotator_raw_sptr
+ gr_make_annotator_raw(size_t sizeof_stream_item);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_map_bb.i b/gnuradio-core/src/lib/general/gr_annotator_raw.i
index 9c8bff6447..85777ef5d4 100644
--- a/gnuradio-core/src/lib/general/gr_map_bb.i
+++ b/gnuradio-core/src/lib/general/gr_annotator_raw.i
@@ -1,32 +1,26 @@
/* -*- c++ -*- */
/*
- * Copyright 2006 Free Software Foundation, Inc.
- *
+ * Copyright 2010-2011 Free Software Foundation, Inc.
+ *
* This file is part of GNU Radio
- *
+ *
* GNU Radio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
- *
+ *
* GNU Radio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Radio; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
-GR_SWIG_BLOCK_MAGIC(gr,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);
-};
+GR_SWIG_BLOCK_MAGIC(gr,annotator_raw);
+%include <pmt_swig.i>
+%include <gr_annotator_raw.h>
diff --git a/gnuradio-core/src/lib/general/gr_bytes_to_syms.cc b/gnuradio-core/src/lib/general/gr_bytes_to_syms.cc
deleted file mode 100644
index 7dafa29f99..0000000000
--- a/gnuradio-core/src/lib/general/gr_bytes_to_syms.cc
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2010 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gr_bytes_to_syms.h>
-#include <gr_io_signature.h>
-#include <assert.h>
-
-static const int BITS_PER_BYTE = 8;
-
-gr_bytes_to_syms_sptr
-gr_make_bytes_to_syms ()
-{
- return gnuradio::get_initial_sptr(new gr_bytes_to_syms ());
-}
-
-gr_bytes_to_syms::gr_bytes_to_syms ()
- : gr_sync_interpolator ("bytes_to_syms",
- gr_make_io_signature (1, 1, sizeof (unsigned char)),
- gr_make_io_signature (1, 1, sizeof (float)),
- BITS_PER_BYTE)
-{
-}
-
-int
-gr_bytes_to_syms::work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- const unsigned char *in = (unsigned char *) input_items[0];
- float *out = (float *) output_items[0];
-
- assert (noutput_items % BITS_PER_BYTE == 0);
-
- for (int i = 0; i < noutput_items / BITS_PER_BYTE; i++){
- int x = in[i];
-
- *out++ = (((x >> 7) & 0x1) << 1) - 1;
- *out++ = (((x >> 6) & 0x1) << 1) - 1;
- *out++ = (((x >> 5) & 0x1) << 1) - 1;
- *out++ = (((x >> 4) & 0x1) << 1) - 1;
- *out++ = (((x >> 3) & 0x1) << 1) - 1;
- *out++ = (((x >> 2) & 0x1) << 1) - 1;
- *out++ = (((x >> 1) & 0x1) << 1) - 1;
- *out++ = (((x >> 0) & 0x1) << 1) - 1;
- }
-
- return noutput_items;
-}
-
-
-
diff --git a/gnuradio-core/src/lib/general/gr_bytes_to_syms.h b/gnuradio-core/src/lib/general/gr_bytes_to_syms.h
deleted file mode 100644
index 23e5c6b91b..0000000000
--- a/gnuradio-core/src/lib/general/gr_bytes_to_syms.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-#ifndef INCLUDED_GR_BYTES_TO_SYMS_H
-#define INCLUDED_GR_BYTES_TO_SYMS_H
-
-#include <gr_core_api.h>
-#include <gr_sync_interpolator.h>
-
-class gr_bytes_to_syms;
-typedef boost::shared_ptr<gr_bytes_to_syms> gr_bytes_to_syms_sptr;
-
-GR_CORE_API gr_bytes_to_syms_sptr gr_make_bytes_to_syms ();
-
-/*!
- * \brief Convert stream of bytes to stream of +/- 1 symbols
- * \ingroup converter_blk
- *
- * input: stream of bytes; output: stream of float
- *
- * This block is deprecated.
- *
- * The combination of gr_packed_to_unpacked_bb followed by
- * gr_chunks_to_symbols_bf or gr_chunks_to_symbols_bc handles the
- * general case of mapping from a stream of bytes into arbitrary float
- * or complex symbols.
- *
- * \sa gr_packed_to_unpacked_bb, gr_unpacked_to_packed_bb,
- * \sa gr_chunks_to_symbols_bf, gr_chunks_to_symbols_bc.
- */
-class GR_CORE_API gr_bytes_to_syms : public gr_sync_interpolator
-{
- friend GR_CORE_API gr_bytes_to_syms_sptr gr_make_bytes_to_syms ();
-
- gr_bytes_to_syms ();
-
- public:
- int work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-};
-
-#endif /* INCLUDED_GR_BYTES_TO_SYMS_H */
diff --git a/gnuradio-core/src/lib/general/gr_char_to_float.cc b/gnuradio-core/src/lib/general/gr_char_to_float.cc
index aec7ad8522..f63aa5b169 100644
--- a/gnuradio-core/src/lib/general/gr_char_to_float.cc
+++ b/gnuradio-core/src/lib/general/gr_char_to_float.cc
@@ -42,7 +42,7 @@ gr_char_to_float::gr_char_to_float (size_t vlen, float scale)
{
const int alignment_multiple =
volk_get_alignment() / sizeof(float);
- set_alignment(alignment_multiple);
+ set_alignment(std::max(1,alignment_multiple));
}
float
diff --git a/gnuradio-core/src/lib/general/gr_char_to_short.cc b/gnuradio-core/src/lib/general/gr_char_to_short.cc
index c20d6cd888..bb9bd8909e 100644
--- a/gnuradio-core/src/lib/general/gr_char_to_short.cc
+++ b/gnuradio-core/src/lib/general/gr_char_to_short.cc
@@ -42,7 +42,7 @@ gr_char_to_short::gr_char_to_short (size_t vlen)
{
const int alignment_multiple =
volk_get_alignment() / sizeof(char);
- set_alignment(alignment_multiple);
+ set_alignment(std::max(1,alignment_multiple));
}
int
diff --git a/gnuradio-core/src/lib/general/gr_complex_to_xxx.cc b/gnuradio-core/src/lib/general/gr_complex_to_xxx.cc
index 3b1fbf9acd..cdf6d7f3a6 100644
--- a/gnuradio-core/src/lib/general/gr_complex_to_xxx.cc
+++ b/gnuradio-core/src/lib/general/gr_complex_to_xxx.cc
@@ -45,7 +45,7 @@ gr_complex_to_float::gr_complex_to_float (unsigned int vlen)
{
const int alignment_multiple =
volk_get_alignment() / sizeof(float);
- set_alignment(alignment_multiple);
+ set_alignment(std::max(1,alignment_multiple));
}
int
@@ -106,7 +106,7 @@ gr_complex_to_real::gr_complex_to_real (unsigned int vlen)
{
const int alignment_multiple =
volk_get_alignment() / sizeof(float);
- set_alignment(alignment_multiple);
+ set_alignment(std::max(1,alignment_multiple));
}
int
@@ -146,7 +146,7 @@ gr_complex_to_imag::gr_complex_to_imag (unsigned int vlen)
{
const int alignment_multiple =
volk_get_alignment() / sizeof(float);
- set_alignment(alignment_multiple);
+ set_alignment(std::max(1,alignment_multiple));
}
int
@@ -186,7 +186,7 @@ gr_complex_to_mag::gr_complex_to_mag (unsigned int vlen)
{
const int alignment_multiple =
volk_get_alignment() / sizeof(float);
- set_alignment(alignment_multiple);
+ set_alignment(std::max(1,alignment_multiple));
}
int
@@ -220,7 +220,7 @@ gr_complex_to_mag_squared::gr_complex_to_mag_squared (unsigned int vlen)
{
const int alignment_multiple =
volk_get_alignment() / sizeof(float);
- set_alignment(alignment_multiple);
+ set_alignment(std::max(1,alignment_multiple));
}
int
@@ -258,7 +258,7 @@ gr_complex_to_arg::gr_complex_to_arg (unsigned int vlen)
{
const int alignment_multiple =
volk_get_alignment() / sizeof(float);
- set_alignment(alignment_multiple);
+ set_alignment(std::max(1,alignment_multiple));
}
int
diff --git a/gnuradio-core/src/lib/general/gr_conjugate_cc.cc b/gnuradio-core/src/lib/general/gr_conjugate_cc.cc
index aaa7f490c7..94ac3e162b 100644
--- a/gnuradio-core/src/lib/general/gr_conjugate_cc.cc
+++ b/gnuradio-core/src/lib/general/gr_conjugate_cc.cc
@@ -43,7 +43,7 @@ gr_conjugate_cc::gr_conjugate_cc ()
{
const int alignment_multiple =
volk_get_alignment() / sizeof(gr_complex);
- set_alignment(alignment_multiple);
+ set_alignment(std::max(1,alignment_multiple));
}
int
diff --git a/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.cc b/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.cc
deleted file mode 100644
index 73ded3c8b3..0000000000
--- a/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2006,2010,2011 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gr_correlate_access_code_tag_bb.h>
-#include <gr_io_signature.h>
-#include <stdexcept>
-#include <gr_count_bits.h>
-#include <cstdio>
-#include <iostream>
-
-#define VERBOSE 0
-
-
-gr_correlate_access_code_tag_bb_sptr
-gr_make_correlate_access_code_tag_bb (const std::string &access_code, int threshold, const std::string &tag_name)
-{
- return gnuradio::get_initial_sptr(new gr_correlate_access_code_tag_bb (access_code, threshold, tag_name));
-}
-
-
-gr_correlate_access_code_tag_bb::gr_correlate_access_code_tag_bb (
- const std::string &access_code, int threshold, const std::string &tag_name)
- : gr_sync_block ("correlate_access_code_tag_bb",
- gr_make_io_signature (1, 1, sizeof(char)),
- gr_make_io_signature (1, 1, sizeof(char))),
- d_data_reg(0), d_mask(0),
- d_threshold(threshold), d_len(0)
-
-{
- if (!set_access_code(access_code)){
- fprintf(stderr, "gr_correlate_access_code_tag_bb: access_code is > 64 bits\n");
- throw std::out_of_range ("access_code is > 64 bits");
- }
-
- std::stringstream str;
- str << name() << unique_id();
- d_me = pmt::pmt_string_to_symbol(str.str());
- d_key = pmt::pmt_string_to_symbol(tag_name);
-}
-
-gr_correlate_access_code_tag_bb::~gr_correlate_access_code_tag_bb ()
-{
-}
-
-bool
-gr_correlate_access_code_tag_bb::set_access_code(
- const std::string &access_code)
-{
- d_len = access_code.length(); // # of bytes in string
- if (d_len > 64)
- return false;
-
- // set len top bits to 1.
- d_mask = ((~0ULL) >> (64 - d_len)) << (64 - d_len);
-
- d_access_code = 0;
- for (unsigned i=0; i < 64; i++){
- d_access_code <<= 1;
- if (i < d_len)
- d_access_code |= access_code[i] & 1; // look at LSB only
- }
-
- return true;
-}
-
-int
-gr_correlate_access_code_tag_bb::work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- const unsigned char *in = (const unsigned char *) input_items[0];
- unsigned char *out = (unsigned char *) output_items[0];
-
- uint64_t abs_out_sample_cnt = nitems_written(0);
-
- for (int i = 0; i < noutput_items; i++){
-
- out[i] = in[i];
-
- // compute hamming distance between desired access code and current data
- unsigned long long wrong_bits = 0;
- unsigned int nwrong = d_threshold+1;
- int new_flag = 0;
-
- wrong_bits = (d_data_reg ^ d_access_code) & d_mask;
- nwrong = gr_count_bits64(wrong_bits);
-
- // test for access code with up to threshold errors
- new_flag = (nwrong <= d_threshold);
-
- // shift in new data and new flag
- d_data_reg = (d_data_reg << 1) | (in[i] & 0x1);
- if (new_flag) {
- if(VERBOSE) std::cout << "writing tag at sample " << abs_out_sample_cnt + i << std::endl;
- add_item_tag(0, //stream ID
- abs_out_sample_cnt + i - 64 + d_len, //sample
- d_key, //frame info
- pmt::pmt_t(), //data (unused)
- d_me //block src id
- );
- }
- }
-
- return noutput_items;
-}
-
diff --git a/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.h b/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.h
deleted file mode 100644
index 345d3004a5..0000000000
--- a/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2005,2006,2011 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef INCLUDED_gr_correlate_access_code_tag_bb_H
-#define INCLUDED_gr_correlate_access_code_tag_bb_H
-
-#include <gr_core_api.h>
-#include <gr_sync_block.h>
-#include <string>
-
-class gr_correlate_access_code_tag_bb;
-typedef boost::shared_ptr<gr_correlate_access_code_tag_bb> gr_correlate_access_code_tag_bb_sptr;
-
-/*!
- * \param access_code is represented with 1 byte per bit, e.g., "010101010111000100"
- * \param threshold maximum number of bits that may be wrong
- * \param tag_name key of the tag inserted into the tag stream
- */
-GR_CORE_API gr_correlate_access_code_tag_bb_sptr
-gr_make_correlate_access_code_tag_bb (const std::string &access_code, int threshold,
- const std::string &tag_name);
-
-/*!
- * \brief Examine input for specified access code, one bit at a time.
- * \ingroup sync_blk
- *
- * input: stream of bits, 1 bit per input byte (data in LSB)
- * output: unaltered stream of bits (plus tags)
- *
- * This block annotates the input stream with tags. The tags have key
- * name [tag_name], specified in the constructor. Used for searching
- * an input data stream for preambles, etc.
- */
-class GR_CORE_API gr_correlate_access_code_tag_bb : public gr_sync_block
-{
- friend GR_CORE_API gr_correlate_access_code_tag_bb_sptr
- gr_make_correlate_access_code_tag_bb (const std::string &access_code, int threshold,
- const std::string &tag_name);
- private:
- unsigned long long d_access_code; // access code to locate start of packet
- // access code is left justified in the word
- unsigned long long d_data_reg; // used to look for access_code
- unsigned long long d_mask; // masks access_code bits (top N bits are set where
- // N is the number of bits in the access code)
- unsigned int d_threshold; // how many bits may be wrong in sync vector
- unsigned int d_len; //the length of the access code
-
- pmt::pmt_t d_key, d_me; //d_key is the tag name, d_me is the block name + unique ID
-
- protected:
- gr_correlate_access_code_tag_bb(const std::string &access_code, int threshold,
- const std::string &tag_name);
-
- public:
- ~gr_correlate_access_code_tag_bb();
-
- int work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-
-
- /*!
- * \param access_code is represented with 1 byte per bit, e.g., "010101010111000100"
- */
- bool set_access_code (const std::string &access_code);
-};
-
-#endif /* INCLUDED_gr_correlate_access_code_tag_bb_H */
diff --git a/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.i b/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.i
deleted file mode 100644
index f7ca4bea7b..0000000000
--- a/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.i
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-GR_SWIG_BLOCK_MAGIC(gr,correlate_access_code_tag_bb);
-
-/*!
- * \param access_code is represented with 1 byte per bit, e.g., "010101010111000100"
- * \param threshold maximum number of bits that may be wrong
- */
-gr_correlate_access_code_tag_bb_sptr
-gr_make_correlate_access_code_tag_bb (const std::string &access_code, int threshold, const std::string &tag_name)
- throw(std::out_of_range);
-
-/*!
- * \brief Examine input for specified access code, one bit at a time.
- * \ingroup block
- *
- * input: stream of bits, 1 bit per input byte (data in LSB)
- * output: stream of bits, 2 bits per output byte (data in LSB, flag in next higher bit)
- *
- * Each output byte contains two valid bits, the data bit, and the
- * flag bit. The LSB (bit 0) is the data bit, and is the original
- * input data, delayed 64 bits. Bit 1 is the
- * flag bit and is 1 if the corresponding data bit is the first data
- * bit following the access code. Otherwise the flag bit is 0.
- */
-class gr_correlate_access_code_tag_bb : public gr_sync_block
-{
- friend gr_correlate_access_code_tag_bb_sptr
- gr_make_correlate_access_code_tag_bb (const std::string &access_code, int threshold, const std::string &tag_name);
- protected:
- gr_correlate_access_code_tag_bb(const std::string &access_code, int threshold, const std::string &tag_name);
-
- public:
- ~gr_correlate_access_code_tag_bb();
-
- /*!
- * \param access_code is represented with 1 byte per bit, e.g., "010101010111000100"
- */
- bool set_access_code (const std::string &access_code);
-};
diff --git a/gnuradio-core/src/lib/general/gr_descrambler_bb.cc b/gnuradio-core/src/lib/general/gr_descrambler_bb.cc
deleted file mode 100644
index b5ae28fa97..0000000000
--- a/gnuradio-core/src/lib/general/gr_descrambler_bb.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008,2010 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gr_descrambler_bb.h>
-#include <gr_io_signature.h>
-
-gr_descrambler_bb_sptr
-gr_make_descrambler_bb(int mask, int seed, int len)
-{
- return gnuradio::get_initial_sptr(new gr_descrambler_bb(mask, seed, len));
-}
-
-gr_descrambler_bb::gr_descrambler_bb(int mask, int seed, int len)
- : gr_sync_block("descrambler_bb",
- gr_make_io_signature (1, 1, sizeof (unsigned char)),
- gr_make_io_signature (1, 1, sizeof (unsigned char))),
- d_lfsr(mask, seed, len)
-{
-}
-
-int
-gr_descrambler_bb::work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- const unsigned char *in = (const unsigned char *) input_items[0];
- unsigned char *out = (unsigned char *) output_items[0];
-
- for (int i = 0; i < noutput_items; i++)
- out[i] = d_lfsr.next_bit_descramble(in[i]);
-
- return noutput_items;
-}
diff --git a/gnuradio-core/src/lib/general/gr_descrambler_bb.h b/gnuradio-core/src/lib/general/gr_descrambler_bb.h
deleted file mode 100644
index 333593caaf..0000000000
--- a/gnuradio-core/src/lib/general/gr_descrambler_bb.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-#ifndef INCLUDED_GR_DESCRAMBLER_BB_H
-#define INCLUDED_GR_DESCRAMBLER_BB_H
-
-#include <gr_core_api.h>
-#include <gr_sync_block.h>
-#include "gri_lfsr.h"
-
-class gr_descrambler_bb;
-typedef boost::shared_ptr<gr_descrambler_bb> gr_descrambler_bb_sptr;
-
-GR_CORE_API gr_descrambler_bb_sptr gr_make_descrambler_bb(int mask, int seed, int len);
-
-/*!
- * Descramble an input stream using an LFSR. This block works on the LSB only
- * of the input data stream, i.e., on an "unpacked binary" stream, and
- * produces the same format on its output.
- *
- * \param mask Polynomial mask for LFSR
- * \param seed Initial shift register contents
- * \param len Shift register length
- *
- * \ingroup coding_blk
- */
-
-class GR_CORE_API gr_descrambler_bb : public gr_sync_block
-{
- friend GR_CORE_API gr_descrambler_bb_sptr gr_make_descrambler_bb(int mask, int seed, int len);
-
- gri_lfsr d_lfsr;
-
- gr_descrambler_bb(int mask, int seed, int len);
-
-public:
- int work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-};
-
-#endif /* INCLUDED_GR_DESCRAMBLER_BB_H */
diff --git a/gnuradio-core/src/lib/general/gr_descrambler_bb.i b/gnuradio-core/src/lib/general/gr_descrambler_bb.i
deleted file mode 100644
index c6cd0a2852..0000000000
--- a/gnuradio-core/src/lib/general/gr_descrambler_bb.i
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-GR_SWIG_BLOCK_MAGIC(gr,descrambler_bb);
-
-gr_descrambler_bb_sptr gr_make_descrambler_bb(int mask, int seed, int len);
-
-class gr_descrambler_bb : public gr_sync_block
-{
-private:
- gr_descrambler_bb(int mask, int seed, int len);
-};
diff --git a/gnuradio-core/src/lib/general/gr_diff_decoder_bb.cc b/gnuradio-core/src/lib/general/gr_diff_decoder_bb.cc
deleted file mode 100644
index 74324a62ea..0000000000
--- a/gnuradio-core/src/lib/general/gr_diff_decoder_bb.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006,2010 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gr_diff_decoder_bb.h>
-#include <gr_io_signature.h>
-
-gr_diff_decoder_bb_sptr
-gr_make_diff_decoder_bb (unsigned int modulus)
-{
- return gnuradio::get_initial_sptr(new gr_diff_decoder_bb(modulus));
-}
-
-gr_diff_decoder_bb::gr_diff_decoder_bb (unsigned int modulus)
- : gr_sync_block ("diff_decoder_bb",
- gr_make_io_signature (1, 1, sizeof (unsigned char)),
- gr_make_io_signature (1, 1, sizeof (unsigned char))),
- d_modulus(modulus)
-{
- set_history(2); // need to look at two inputs
-}
-
-int
-gr_diff_decoder_bb::work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- const unsigned char *in = (const unsigned char *) input_items[0];
- unsigned char *out = (unsigned char *) output_items[0];
- in += 1; // ensure that in[-1] is valid
-
- unsigned modulus = d_modulus;
-
- for (int i = 0; i < noutput_items; i++){
- out[i] = (in[i] - in[i-1]) % modulus;
- }
-
- return noutput_items;
-}
diff --git a/gnuradio-core/src/lib/general/gr_diff_decoder_bb.h b/gnuradio-core/src/lib/general/gr_diff_decoder_bb.h
deleted file mode 100644
index c4ebbc4765..0000000000
--- a/gnuradio-core/src/lib/general/gr_diff_decoder_bb.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef INCLUDED_GR_DIFF_DECODER_BB_H
-#define INCLUDED_GR_DIFF_DECODER_BB_H
-
-#include <gr_core_api.h>
-#include <gr_sync_block.h>
-
-class gr_diff_decoder_bb;
-typedef boost::shared_ptr<gr_diff_decoder_bb> gr_diff_decoder_bb_sptr;
-
-GR_CORE_API gr_diff_decoder_bb_sptr gr_make_diff_decoder_bb (unsigned int modulus);
-
-/*!
- * \brief y[0] = (x[0] - x[-1]) % M
- * \ingroup coding_blk
- *
- * Differential decoder
- */
-class GR_CORE_API gr_diff_decoder_bb : public gr_sync_block
-{
- friend GR_CORE_API gr_diff_decoder_bb_sptr gr_make_diff_decoder_bb (unsigned int modulus);
- gr_diff_decoder_bb(unsigned int modulus);
-
- unsigned int d_modulus;
-
- public:
- int work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-};
-
-#endif
diff --git a/gnuradio-core/src/lib/general/gr_diff_encoder_bb.cc b/gnuradio-core/src/lib/general/gr_diff_encoder_bb.cc
deleted file mode 100644
index 98492c746e..0000000000
--- a/gnuradio-core/src/lib/general/gr_diff_encoder_bb.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006,2010 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gr_diff_encoder_bb.h>
-#include <gr_io_signature.h>
-
-gr_diff_encoder_bb_sptr
-gr_make_diff_encoder_bb (unsigned int modulus)
-{
- return gnuradio::get_initial_sptr(new gr_diff_encoder_bb(modulus));
-}
-
-gr_diff_encoder_bb::gr_diff_encoder_bb (unsigned int modulus)
- : gr_sync_block ("diff_encoder_bb",
- gr_make_io_signature (1, 1, sizeof (unsigned char)),
- gr_make_io_signature (1, 1, sizeof (unsigned char))),
- d_last_out(0), d_modulus(modulus)
-{
-}
-
-int
-gr_diff_encoder_bb::work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- const unsigned char *in = (const unsigned char *) input_items[0];
- unsigned char *out = (unsigned char *) output_items[0];
-
- unsigned last_out = d_last_out;
- unsigned modulus = d_modulus;
-
- for (int i = 0; i < noutput_items; i++){
- out[i] = (in[i] + last_out) % modulus;
- last_out = out[i];
- }
-
- d_last_out = last_out;
- return noutput_items;
-}
diff --git a/gnuradio-core/src/lib/general/gr_diff_encoder_bb.h b/gnuradio-core/src/lib/general/gr_diff_encoder_bb.h
deleted file mode 100644
index e98876b700..0000000000
--- a/gnuradio-core/src/lib/general/gr_diff_encoder_bb.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef INCLUDED_GR_DIFF_ENCODER_BB_H
-#define INCLUDED_GR_DIFF_ENCODER_BB_H
-
-#include <gr_core_api.h>
-#include <gr_sync_block.h>
-
-class gr_diff_encoder_bb;
-typedef boost::shared_ptr<gr_diff_encoder_bb> gr_diff_encoder_bb_sptr;
-
-GR_CORE_API gr_diff_encoder_bb_sptr gr_make_diff_encoder_bb (unsigned int modulus);
-
-/*!
- * \brief y[0] = (x[0] + y[-1]) % M
- * \ingroup coding_blk
- *
- * Differential encoder
- */
-class GR_CORE_API gr_diff_encoder_bb : public gr_sync_block
-{
- friend GR_CORE_API gr_diff_encoder_bb_sptr gr_make_diff_encoder_bb (unsigned int modulus);
- gr_diff_encoder_bb(unsigned int modulus);
-
- unsigned int d_last_out;
- unsigned int d_modulus;
-
- public:
- int work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-};
-
-#endif
diff --git a/gnuradio-core/src/lib/general/gr_diff_phasor_cc.cc b/gnuradio-core/src/lib/general/gr_diff_phasor_cc.cc
deleted file mode 100644
index 89fa2041e7..0000000000
--- a/gnuradio-core/src/lib/general/gr_diff_phasor_cc.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006,2010 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gr_diff_phasor_cc.h>
-#include <gr_io_signature.h>
-
-gr_diff_phasor_cc_sptr
-gr_make_diff_phasor_cc ()
-{
- return gnuradio::get_initial_sptr(new gr_diff_phasor_cc());
-}
-
-gr_diff_phasor_cc::gr_diff_phasor_cc ()
- : gr_sync_block ("diff_phasor_cc",
- gr_make_io_signature (1, 1, sizeof (gr_complex)),
- gr_make_io_signature (1, 1, sizeof (gr_complex)))
-{
- set_history(2);
-}
-
-
-gr_diff_phasor_cc::~gr_diff_phasor_cc(){}
-
-int
-gr_diff_phasor_cc::work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- gr_complex const *in = (const gr_complex *) input_items[0];
- gr_complex *out = (gr_complex *) output_items[0];
- in += 1; // ensure that i - 1 is valid.
-
- for(int i = 0; i < noutput_items; i++){
- out[i] = in[i] * conj(in[i-1]);
- }
-
- return noutput_items;
-}
diff --git a/gnuradio-core/src/lib/general/gr_float_to_char.cc b/gnuradio-core/src/lib/general/gr_float_to_char.cc
index 3602ad7453..d67ded3ea6 100644
--- a/gnuradio-core/src/lib/general/gr_float_to_char.cc
+++ b/gnuradio-core/src/lib/general/gr_float_to_char.cc
@@ -42,7 +42,7 @@ gr_float_to_char::gr_float_to_char (size_t vlen, float scale)
{
const int alignment_multiple =
volk_get_alignment() / sizeof(char);
- set_alignment(alignment_multiple);
+ set_alignment(std::max(1,alignment_multiple));
}
float
diff --git a/gnuradio-core/src/lib/general/gr_float_to_int.cc b/gnuradio-core/src/lib/general/gr_float_to_int.cc
index bd3cd6a3b3..43b8518956 100644
--- a/gnuradio-core/src/lib/general/gr_float_to_int.cc
+++ b/gnuradio-core/src/lib/general/gr_float_to_int.cc
@@ -43,7 +43,7 @@ gr_float_to_int::gr_float_to_int (size_t vlen, float scale)
{
const int alignment_multiple =
volk_get_alignment() / sizeof(int);
- set_alignment(alignment_multiple);
+ set_alignment(std::max(1,alignment_multiple));
}
float
diff --git a/gnuradio-core/src/lib/general/gr_float_to_short.cc b/gnuradio-core/src/lib/general/gr_float_to_short.cc
index 07995c99aa..ab720168bf 100644
--- a/gnuradio-core/src/lib/general/gr_float_to_short.cc
+++ b/gnuradio-core/src/lib/general/gr_float_to_short.cc
@@ -42,7 +42,7 @@ gr_float_to_short::gr_float_to_short (size_t vlen, float scale)
{
const int alignment_multiple =
volk_get_alignment() / sizeof(short);
- set_alignment(alignment_multiple);
+ set_alignment(std::max(1,alignment_multiple));
}
float
diff --git a/gnuradio-core/src/lib/general/gr_framer_sink_1.cc b/gnuradio-core/src/lib/general/gr_framer_sink_1.cc
deleted file mode 100644
index 64a0af6a07..0000000000
--- a/gnuradio-core/src/lib/general/gr_framer_sink_1.cc
+++ /dev/null
@@ -1,190 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2006,2010 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gr_framer_sink_1.h>
-#include <gr_io_signature.h>
-#include <cstdio>
-#include <stdexcept>
-#include <string.h>
-
-#define VERBOSE 0
-
-inline void
-gr_framer_sink_1::enter_search()
-{
- if (VERBOSE)
- fprintf(stderr, "@ enter_search\n");
-
- d_state = STATE_SYNC_SEARCH;
-}
-
-inline void
-gr_framer_sink_1::enter_have_sync()
-{
- if (VERBOSE)
- fprintf(stderr, "@ enter_have_sync\n");
-
- d_state = STATE_HAVE_SYNC;
- d_header = 0;
- d_headerbitlen_cnt = 0;
-}
-
-inline void
-gr_framer_sink_1::enter_have_header(int payload_len, int whitener_offset)
-{
- if (VERBOSE)
- fprintf(stderr, "@ enter_have_header (payload_len = %d) (offset = %d)\n", payload_len, whitener_offset);
-
- d_state = STATE_HAVE_HEADER;
- d_packetlen = payload_len;
- d_packet_whitener_offset = whitener_offset;
- d_packetlen_cnt = 0;
- d_packet_byte = 0;
- d_packet_byte_index = 0;
-}
-
-gr_framer_sink_1_sptr
-gr_make_framer_sink_1(gr_msg_queue_sptr target_queue)
-{
- return gnuradio::get_initial_sptr(new gr_framer_sink_1(target_queue));
-}
-
-
-gr_framer_sink_1::gr_framer_sink_1(gr_msg_queue_sptr target_queue)
- : gr_sync_block ("framer_sink_1",
- gr_make_io_signature (1, 1, sizeof(unsigned char)),
- gr_make_io_signature (0, 0, 0)),
- d_target_queue(target_queue)
-{
- enter_search();
-}
-
-gr_framer_sink_1::~gr_framer_sink_1 ()
-{
-}
-
-int
-gr_framer_sink_1::work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- const unsigned char *in = (const unsigned char *) input_items[0];
- int count=0;
-
- if (VERBOSE)
- fprintf(stderr,">>> Entering state machine\n");
-
- while (count < noutput_items){
- switch(d_state) {
-
- case STATE_SYNC_SEARCH: // Look for flag indicating beginning of pkt
- if (VERBOSE)
- fprintf(stderr,"SYNC Search, noutput=%d\n", noutput_items);
-
- while (count < noutput_items) {
- if (in[count] & 0x2){ // Found it, set up for header decode
- enter_have_sync();
- break;
- }
- count++;
- }
- break;
-
- case STATE_HAVE_SYNC:
- if (VERBOSE)
- fprintf(stderr,"Header Search bitcnt=%d, header=0x%08x\n",
- d_headerbitlen_cnt, d_header);
-
- while (count < noutput_items) { // Shift bits one at a time into header
- d_header = (d_header << 1) | (in[count++] & 0x1);
- if (++d_headerbitlen_cnt == HEADERBITLEN) {
-
- if (VERBOSE)
- fprintf(stderr, "got header: 0x%08x\n", d_header);
-
- // we have a full header, check to see if it has been received properly
- if (header_ok()){
- int payload_len;
- int whitener_offset;
- header_payload(&payload_len, &whitener_offset);
- enter_have_header(payload_len, whitener_offset);
-
- if (d_packetlen == 0){ // check for zero-length payload
- // build a zero-length message
- // NOTE: passing header field as arg1 is not scalable
- gr_message_sptr msg =
- gr_make_message(0, d_packet_whitener_offset, 0, 0);
-
- d_target_queue->insert_tail(msg); // send it
- msg.reset(); // free it up
-
- enter_search();
- }
- }
- else
- enter_search(); // bad header
- break; // we're in a new state
- }
- }
- break;
-
- case STATE_HAVE_HEADER:
- if (VERBOSE)
- fprintf(stderr,"Packet Build\n");
-
- while (count < noutput_items) { // shift bits into bytes of packet one at a time
- d_packet_byte = (d_packet_byte << 1) | (in[count++] & 0x1);
- if (d_packet_byte_index++ == 7) { // byte is full so move to next byte
- d_packet[d_packetlen_cnt++] = d_packet_byte;
- d_packet_byte_index = 0;
-
- if (d_packetlen_cnt == d_packetlen){ // packet is filled
-
- // build a message
- // NOTE: passing header field as arg1 is not scalable
- gr_message_sptr msg =
- gr_make_message(0, d_packet_whitener_offset, 0, d_packetlen_cnt);
- memcpy(msg->msg(), d_packet, d_packetlen_cnt);
-
- d_target_queue->insert_tail(msg); // send it
- msg.reset(); // free it up
-
- enter_search();
- break;
- }
- }
- }
- break;
-
- default:
- assert(0);
-
- } // switch
-
- } // while
-
- return noutput_items;
-}
diff --git a/gnuradio-core/src/lib/general/gr_framer_sink_1.h b/gnuradio-core/src/lib/general/gr_framer_sink_1.h
deleted file mode 100644
index 93e41745f3..0000000000
--- a/gnuradio-core/src/lib/general/gr_framer_sink_1.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2005,2006 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef INCLUDED_GR_FRAMER_SINK_1_H
-#define INCLUDED_GR_FRAMER_SINK_1_H
-
-#include <gr_core_api.h>
-#include <gr_sync_block.h>
-#include <gr_msg_queue.h>
-
-class gr_framer_sink_1;
-typedef boost::shared_ptr<gr_framer_sink_1> gr_framer_sink_1_sptr;
-
-GR_CORE_API gr_framer_sink_1_sptr
-gr_make_framer_sink_1 (gr_msg_queue_sptr target_queue);
-
-/*!
- * \brief Given a stream of bits and access_code flags, assemble packets.
- * \ingroup sink_blk
- *
- * input: stream of bytes from gr_correlate_access_code_bb
- * output: none. Pushes assembled packet into target queue
- *
- * The framer expects a fixed length header of 2 16-bit shorts
- * containing the payload length, followed by the payload. If the
- * 2 16-bit shorts are not identical, this packet is ignored. Better
- * algs are welcome.
- *
- * The input data consists of bytes that have two bits used.
- * Bit 0, the LSB, contains the data bit.
- * Bit 1 if set, indicates that the corresponding bit is the
- * the first bit of the packet. That is, this bit is the first
- * one after the access code.
- */
-class GR_CORE_API gr_framer_sink_1 : public gr_sync_block
-{
- friend GR_CORE_API gr_framer_sink_1_sptr
- gr_make_framer_sink_1 (gr_msg_queue_sptr target_queue);
-
- private:
- enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER};
-
- static const int MAX_PKT_LEN = 4096;
- static const int HEADERBITLEN = 32;
-
- gr_msg_queue_sptr d_target_queue; // where to send the packet when received
- state_t d_state;
- unsigned int d_header; // header bits
- int d_headerbitlen_cnt; // how many so far
-
- unsigned char d_packet[MAX_PKT_LEN]; // assembled payload
- unsigned char d_packet_byte; // byte being assembled
- int d_packet_byte_index; // which bit of d_packet_byte we're working on
- int d_packetlen; // length of packet
- int d_packet_whitener_offset; // offset into whitener string to use
- int d_packetlen_cnt; // how many so far
-
- protected:
- gr_framer_sink_1(gr_msg_queue_sptr target_queue);
-
- void enter_search();
- void enter_have_sync();
- void enter_have_header(int payload_len, int whitener_offset);
-
- bool header_ok()
- {
- // confirm that two copies of header info are identical
- return ((d_header >> 16) ^ (d_header & 0xffff)) == 0;
- }
-
- void header_payload(int *len, int *offset)
- {
- // header consists of two 16-bit shorts in network byte order
- // payload length is lower 12 bits
- // whitener offset is upper 4 bits
- *len = (d_header >> 16) & 0x0fff;
- *offset = (d_header >> 28) & 0x000f;
- }
-
- public:
- ~gr_framer_sink_1();
-
- int work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-};
-
-#endif /* INCLUDED_GR_FRAMER_SINK_1_H */
diff --git a/gnuradio-core/src/lib/general/gr_glfsr_source_b.cc b/gnuradio-core/src/lib/general/gr_glfsr_source_b.cc
deleted file mode 100644
index fcfeb80dcf..0000000000
--- a/gnuradio-core/src/lib/general/gr_glfsr_source_b.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,2010 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gr_glfsr_source_b.h>
-#include <gri_glfsr.h>
-#include <gr_io_signature.h>
-#include <stdexcept>
-
-gr_glfsr_source_b_sptr
-gr_make_glfsr_source_b(int degree, bool repeat, int mask, int seed)
-{
- return gnuradio::get_initial_sptr(new gr_glfsr_source_b(degree, repeat, mask, seed));
-}
-
-gr_glfsr_source_b::gr_glfsr_source_b(int degree, bool repeat, int mask, int seed)
- : gr_sync_block ("glfsr_source_b",
- gr_make_io_signature (0, 0, 0),
- gr_make_io_signature (1, 1, sizeof(unsigned char))),
- d_repeat(repeat),
- d_index(0)
-{
- if (degree < 1 || degree > 32)
- throw std::runtime_error("gr_glfsr_source_b: degree must be between 1 and 32 inclusive");
- d_length = (unsigned int)((1ULL << degree)-1);
-
- if (mask == 0)
- mask = gri_glfsr::glfsr_mask(degree);
- d_glfsr = new gri_glfsr(mask, seed);
-}
-
-gr_glfsr_source_b::~gr_glfsr_source_b()
-{
- delete d_glfsr;
-}
-
-int
-gr_glfsr_source_b::work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- char *out = (char *) output_items[0];
- if ((d_index > d_length) && d_repeat == false)
- return -1; /* once through the sequence */
-
- int i;
- for (i = 0; i < noutput_items; i++) {
- out[i] = d_glfsr->next_bit();
- d_index++;
- if (d_index > d_length && d_repeat == false)
- break;
- }
-
- return i;
-}
-
-int
-gr_glfsr_source_b::mask() const
-{
- return d_glfsr->mask();
-}
diff --git a/gnuradio-core/src/lib/general/gr_glfsr_source_b.h b/gnuradio-core/src/lib/general/gr_glfsr_source_b.h
deleted file mode 100644
index 7549a76b32..0000000000
--- a/gnuradio-core/src/lib/general/gr_glfsr_source_b.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef INCLUDED_GR_GLFSR_SOURCE_B_H
-#define INCLUDED_GR_GLFSR_SOURCE_B_H
-
-#include <gr_core_api.h>
-#include <gr_sync_block.h>
-
-class gri_glfsr;
-
-class gr_glfsr_source_b;
-typedef boost::shared_ptr<gr_glfsr_source_b> gr_glfsr_source_b_sptr;
-
-GR_CORE_API gr_glfsr_source_b_sptr gr_make_glfsr_source_b(int degree, bool repeat=true, int mask=0, int seed=1);
-
-/*!
- * \brief Galois LFSR pseudo-random source
- * \ingroup source_blk
- */
-class GR_CORE_API gr_glfsr_source_b : public gr_sync_block
-{
- private:
- friend GR_CORE_API gr_glfsr_source_b_sptr
- gr_make_glfsr_source_b(int degree, bool repeat, int mask, int seed);
-
- gri_glfsr *d_glfsr;
-
- bool d_repeat;
- unsigned int d_index;
- unsigned int d_length;
-
- gr_glfsr_source_b(int degree, bool repeat, int mask, int seed);
-
- public:
-
- ~gr_glfsr_source_b();
-
- int work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-
- unsigned int period() const { return d_length; }
- int mask() const;
-};
-
-#endif /* INCLUDED_GR_GLFSR_SOURCE_B_H */
diff --git a/gnuradio-core/src/lib/general/gr_glfsr_source_b.i b/gnuradio-core/src/lib/general/gr_glfsr_source_b.i
deleted file mode 100644
index ffdd52ddba..0000000000
--- a/gnuradio-core/src/lib/general/gr_glfsr_source_b.i
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-GR_SWIG_BLOCK_MAGIC(gr,glfsr_source_b);
-
-gr_glfsr_source_b_sptr
-gr_make_glfsr_source_b(int degree, bool repeat=true, int mask=0, int seed=1)
- throw (std::runtime_error);
-
-class gr_glfsr_source_b : public gr_sync_block
-{
-protected:
- gr_glfsr_source_b(int degree, bool repeat, int mask, int seed);
-
-public:
- unsigned int period() const;
- int mask() const;
-};
diff --git a/gnuradio-core/src/lib/general/gr_glfsr_source_f.cc b/gnuradio-core/src/lib/general/gr_glfsr_source_f.cc
deleted file mode 100644
index a9efc8a706..0000000000
--- a/gnuradio-core/src/lib/general/gr_glfsr_source_f.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,2010 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gr_glfsr_source_f.h>
-#include <gri_glfsr.h>
-#include <gr_io_signature.h>
-#include <stdexcept>
-
-gr_glfsr_source_f_sptr
-gr_make_glfsr_source_f(int degree, bool repeat, int mask, int seed)
-{
- return gnuradio::get_initial_sptr(new gr_glfsr_source_f(degree, repeat, mask, seed));
-}
-
-gr_glfsr_source_f::gr_glfsr_source_f(int degree, bool repeat, int mask, int seed)
- : gr_sync_block ("glfsr_source_f",
- gr_make_io_signature (0, 0, 0),
- gr_make_io_signature (1, 1, sizeof(float))),
- d_repeat(repeat),
- d_index(0)
-{
- if (degree < 1 || degree > 32)
- throw std::runtime_error("gr_glfsr_source_f: degree must be between 1 and 32 inclusive");
- d_length = (unsigned int)((1ULL << degree)-1);
-
- if (mask == 0)
- mask = gri_glfsr::glfsr_mask(degree);
- d_glfsr = new gri_glfsr(mask, seed);
-}
-
-gr_glfsr_source_f::~gr_glfsr_source_f()
-{
- delete d_glfsr;
-}
-
-int
-gr_glfsr_source_f::work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- float *out = (float *) output_items[0];
- if ((d_index > d_length) && d_repeat == false)
- return -1; /* once through the sequence */
-
- int i;
- for (i = 0; i < noutput_items; i++) {
- out[i] = (float)d_glfsr->next_bit()*2.0-1.0;
- d_index++;
- if (d_index > d_length && d_repeat == false)
- break;
- }
-
- return i;
-}
-
-int
-gr_glfsr_source_f::mask() const
-{
- return d_glfsr->mask();
-}
diff --git a/gnuradio-core/src/lib/general/gr_glfsr_source_f.h b/gnuradio-core/src/lib/general/gr_glfsr_source_f.h
deleted file mode 100644
index 3549e3e5df..0000000000
--- a/gnuradio-core/src/lib/general/gr_glfsr_source_f.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef INCLUDED_GR_GLFSR_SOURCE_F_H
-#define INCLUDED_GR_GLFSR_SOURCE_F_H
-
-#include <gr_core_api.h>
-#include <gr_sync_block.h>
-
-class gri_glfsr;
-
-class gr_glfsr_source_f;
-typedef boost::shared_ptr<gr_glfsr_source_f> gr_glfsr_source_f_sptr;
-
-GR_CORE_API gr_glfsr_source_f_sptr gr_make_glfsr_source_f(int degree, bool repeat=true, int mask=0, int seed=1);
-
-/*!
- * \brief Galois LFSR pseudo-random source generating float outputs -1.0 - 1.0
- * \ingroup source_blk
- */
-class GR_CORE_API gr_glfsr_source_f : public gr_sync_block
-{
- private:
- friend GR_CORE_API gr_glfsr_source_f_sptr
- gr_make_glfsr_source_f(int degree, bool repeat, int mask, int seed);
-
- gri_glfsr *d_glfsr;
-
- bool d_repeat;
- unsigned int d_index;
- unsigned int d_length;
-
- gr_glfsr_source_f(int degree, bool repeat, int mask, int seed);
-
- public:
-
- ~gr_glfsr_source_f();
-
- int work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-
- unsigned int period() const { return d_length; }
- int mask() const;
-};
-
-#endif /* INCLUDED_GR_GLFSR_SOURCE_F_H */
diff --git a/gnuradio-core/src/lib/general/gr_glfsr_source_f.i b/gnuradio-core/src/lib/general/gr_glfsr_source_f.i
deleted file mode 100644
index 2f84387c27..0000000000
--- a/gnuradio-core/src/lib/general/gr_glfsr_source_f.i
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-GR_SWIG_BLOCK_MAGIC(gr,glfsr_source_f);
-
-gr_glfsr_source_f_sptr
-gr_make_glfsr_source_f(int degree, bool repeat=true, int mask=0, int seed=1)
- throw (std::runtime_error);
-
-class gr_glfsr_source_f : public gr_sync_block
-{
-protected:
- gr_glfsr_source_f(int degree, bool repeat, int mask, int seed);
-
-public:
- unsigned int period() const;
- int mask() const;
-};
diff --git a/gnuradio-core/src/lib/general/gr_head.h b/gnuradio-core/src/lib/general/gr_head.h
index 17dd737f0b..48415892dd 100644
--- a/gnuradio-core/src/lib/general/gr_head.h
+++ b/gnuradio-core/src/lib/general/gr_head.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004,2009 Free Software Foundation, Inc.
+ * Copyright 2004,2009,2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -51,6 +51,7 @@ class GR_CORE_API gr_head : public gr_sync_block
gr_vector_void_star &output_items);
void reset() { d_ncopied_items = 0; }
+ void set_length(int nitems) { d_nitems = nitems; }
};
GR_CORE_API gr_head_sptr
diff --git a/gnuradio-core/src/lib/general/gr_head.i b/gnuradio-core/src/lib/general/gr_head.i
index 73feaf181c..11f3331d47 100644
--- a/gnuradio-core/src/lib/general/gr_head.i
+++ b/gnuradio-core/src/lib/general/gr_head.i
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004,2009 Free Software Foundation, Inc.
+ * Copyright 2004,2009,2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -28,5 +28,6 @@ class gr_head : public gr_block {
gr_head();
public:
void reset();
+ void set_length(int nitems);
};
diff --git a/gnuradio-core/src/lib/general/gr_int_to_float.cc b/gnuradio-core/src/lib/general/gr_int_to_float.cc
index a284853055..a7fb24dc69 100644
--- a/gnuradio-core/src/lib/general/gr_int_to_float.cc
+++ b/gnuradio-core/src/lib/general/gr_int_to_float.cc
@@ -42,7 +42,7 @@ gr_int_to_float::gr_int_to_float (size_t vlen, float scale)
{
const int alignment_multiple =
volk_get_alignment() / sizeof(float);
- set_alignment(alignment_multiple);
+ set_alignment(std::max(1,alignment_multiple));
}
int
diff --git a/gnuradio-core/src/lib/general/gr_keep_m_in_n.cc b/gnuradio-core/src/lib/general/gr_keep_m_in_n.cc
new file mode 100644
index 0000000000..1becbfa116
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_keep_m_in_n.cc
@@ -0,0 +1,98 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_keep_m_in_n.h>
+#include <gr_io_signature.h>
+#include <string.h>
+#include <stdio.h>
+
+gr_keep_m_in_n_sptr
+gr_make_keep_m_in_n(size_t item_size, int m, int n, int offset)
+{
+ return gnuradio::get_initial_sptr(new gr_keep_m_in_n(item_size, m, n, offset));
+}
+
+
+/*
+*
+* offset = 0, starts with 0th item
+* offset = 1, starts with 1st item, etc...
+*
+* we take m items out of each n
+*/
+gr_keep_m_in_n::gr_keep_m_in_n(size_t item_size, int m, int n, int offset)
+ : gr_block("keep_m_in_n",
+ gr_make_io_signature(1, 1, item_size),
+ gr_make_io_signature(1, 1, item_size)),
+ d_n(n),
+ d_m(m),
+ d_offset(offset),
+ d_itemsize(item_size)
+{
+ // sanity checking
+ assert(d_m > 0);
+ assert(d_n > 0);
+ assert(d_m <= d_n);
+ assert(d_offset <= (d_n-d_m));
+
+ set_output_multiple(m);
+}
+
+
+void
+gr_keep_m_in_n::forecast(int noutput_items, gr_vector_int &ninput_items_required)
+{
+ ninput_items_required[0] = d_n*(noutput_items/d_m);
+}
+
+void
+gr_keep_m_in_n::set_offset(int offset)
+{
+ d_offset = offset;
+}
+
+int
+gr_keep_m_in_n::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ uint8_t* out = (uint8_t*)output_items[0];
+ const uint8_t* in = (const uint8_t*)input_items[0];
+
+ // iterate over data blocks of size {n, input : m, output}
+ int blks = std::min(noutput_items/d_m, ninput_items[0]/d_n);
+ for(int i=0; i<blks; i++) {
+ // set up copy pointers
+ const uint8_t* iptr = &in[(i*d_n + d_offset)*d_itemsize];
+ uint8_t* optr = &out[i*d_m*d_itemsize];
+ // perform copy
+ memcpy( optr, iptr, d_m*d_itemsize );
+ }
+
+ consume_each(d_n);
+ return d_m;
+}
diff --git a/gnuradio-core/src/lib/general/gr_keep_m_in_n.h b/gnuradio-core/src/lib/general/gr_keep_m_in_n.h
new file mode 100644
index 0000000000..c6bf40ecf2
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_keep_m_in_n.h
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_KEEP_M_IN_N_H
+#define INCLUDED_GR_KEEP_M_IN_N_H
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+
+class gr_keep_m_in_n;
+typedef boost::shared_ptr<gr_keep_m_in_n> gr_keep_m_in_n_sptr;
+
+GR_CORE_API gr_keep_m_in_n_sptr
+gr_make_keep_m_in_n (size_t item_size, int m, int n, int offset);
+
+
+/*!
+ * \brief decimate a stream, keeping one item out of every n.
+ * \ingroup slicedice_blk
+ */
+class GR_CORE_API gr_keep_m_in_n : public gr_block
+{
+ friend GR_CORE_API gr_keep_m_in_n_sptr
+ gr_make_keep_m_in_n (size_t item_size, int m, int n, int offset);
+
+ int d_n;
+ int d_m;
+ int d_count;
+ int d_offset;
+ int d_itemsize;
+
+ protected:
+ gr_keep_m_in_n (size_t item_size, int m, int n, int offset);
+ void forecast (int noutput_items, gr_vector_int &ninput_items_required);
+
+ public:
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ void set_offset(int offset);
+ void set_n(int n){ d_n = n; }
+ void set_m(int m){ d_m = m; }
+
+};
+
+#endif /* INCLUDED_GR_KEEP_M_IN_N_H */
diff --git a/gnuradio-core/src/lib/general/gr_framer_sink_1.i b/gnuradio-core/src/lib/general/gr_keep_m_in_n.i
index 06281b138d..f280c0248a 100644
--- a/gnuradio-core/src/lib/general/gr_framer_sink_1.i
+++ b/gnuradio-core/src/lib/general/gr_keep_m_in_n.i
@@ -1,35 +1,35 @@
/* -*- c++ -*- */
/*
- * Copyright 2004,2006 Free Software Foundation, Inc.
- *
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
* This file is part of GNU Radio
- *
+ *
* GNU Radio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
- *
+ *
* GNU Radio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Radio; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
-GR_SWIG_BLOCK_MAGIC(gr,framer_sink_1);
+GR_SWIG_BLOCK_MAGIC(gr,keep_m_in_n)
-gr_framer_sink_1_sptr
-gr_make_framer_sink_1(gr_msg_queue_sptr target_queue);
+gr_keep_m_in_n_sptr
+gr_make_keep_m_in_n (size_t itemsize, int m, int n, int offset);
-class gr_framer_sink_1 : public gr_sync_block
+class gr_keep_m_in_n : public gr_sync_block
{
protected:
- gr_framer_sink_1(gr_msg_queue_sptr target_queue);
-
+ gr_keep_m_in_n (size_t itemsize, int m, int n, int offset);
public:
- ~gr_framer_sink_1();
+ void set_offset(int offset);
+
};
diff --git a/gnuradio-core/src/lib/general/gr_map_bb.cc b/gnuradio-core/src/lib/general/gr_map_bb.cc
deleted file mode 100644
index 7deb8971a5..0000000000
--- a/gnuradio-core/src/lib/general/gr_map_bb.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006,2007,2010 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gr_map_bb.h>
-#include <gr_io_signature.h>
-
-gr_map_bb_sptr
-gr_make_map_bb (const std::vector<int> &map)
-{
- return gnuradio::get_initial_sptr(new gr_map_bb (map));
-}
-
-gr_map_bb::gr_map_bb (const std::vector<int> &map)
- : gr_sync_block ("map_bb",
- gr_make_io_signature (1, 1, sizeof (unsigned char)),
- gr_make_io_signature (1, 1, sizeof (unsigned char)))
-{
- for (int i = 0; i < 0x100; i++)
- d_map[i] = i;
-
- unsigned int size = std::min((size_t) 0x100, map.size());
- for (unsigned int i = 0; i < size; i++)
- d_map[i] = map[i];
-}
-
-int
-gr_map_bb::work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- const unsigned char *in = (const unsigned char *) input_items[0];
- unsigned char *out = (unsigned char *) output_items[0];
-
- for (int i = 0; i < noutput_items; i++)
- out[i] = d_map[in[i]];
-
- return noutput_items;
-}
diff --git a/gnuradio-core/src/lib/general/gr_multiply_cc.cc b/gnuradio-core/src/lib/general/gr_multiply_cc.cc
index 32c44a19e4..4a3751419f 100644
--- a/gnuradio-core/src/lib/general/gr_multiply_cc.cc
+++ b/gnuradio-core/src/lib/general/gr_multiply_cc.cc
@@ -40,9 +40,9 @@ gr_multiply_cc::gr_multiply_cc (size_t vlen)
gr_make_io_signature (1, 1, sizeof (gr_complex)*vlen)),
d_vlen(vlen)
{
- const int alignment_multiple =
- volk_get_alignment() / sizeof(gr_complex);
- set_alignment(alignment_multiple);
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(gr_complex);
+ set_alignment(std::max(1,alignment_multiple));
}
int
diff --git a/gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.cc b/gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.cc
index 53ede2eeda..0c5fb4a926 100644
--- a/gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.cc
+++ b/gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.cc
@@ -40,9 +40,9 @@ gr_multiply_conjugate_cc::gr_multiply_conjugate_cc (size_t vlen)
gr_make_io_signature (1, 1, sizeof (gr_complex)*vlen)),
d_vlen(vlen)
{
- const int alignment_multiple =
- volk_get_alignment() / sizeof(gr_complex);
- set_alignment(alignment_multiple);
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(gr_complex);
+ set_alignment(std::max(1,alignment_multiple));
}
int
diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_cc.cc b/gnuradio-core/src/lib/general/gr_multiply_const_cc.cc
index 359ab6ba05..bd4511937f 100644
--- a/gnuradio-core/src/lib/general/gr_multiply_const_cc.cc
+++ b/gnuradio-core/src/lib/general/gr_multiply_const_cc.cc
@@ -40,9 +40,9 @@ gr_multiply_const_cc::gr_multiply_const_cc (gr_complex k, size_t vlen)
gr_make_io_signature (1, 1, sizeof (gr_complex)*vlen)),
d_k(k), d_vlen(vlen)
{
- const int alignment_multiple =
- volk_get_alignment() / sizeof(gr_complex);
- set_alignment(alignment_multiple);
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(gr_complex);
+ set_alignment(std::max(1,alignment_multiple));
}
gr_complex
diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_ff.cc b/gnuradio-core/src/lib/general/gr_multiply_const_ff.cc
index 263f066106..16ba39df93 100644
--- a/gnuradio-core/src/lib/general/gr_multiply_const_ff.cc
+++ b/gnuradio-core/src/lib/general/gr_multiply_const_ff.cc
@@ -40,9 +40,9 @@ gr_multiply_const_ff::gr_multiply_const_ff (float k, size_t vlen)
gr_make_io_signature (1, 1, sizeof (float)*vlen)),
d_k(k), d_vlen(vlen)
{
- const int alignment_multiple =
- volk_get_alignment() / sizeof(float);
- set_alignment(alignment_multiple);
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(float);
+ set_alignment(std::max(1,alignment_multiple));
}
float
diff --git a/gnuradio-core/src/lib/general/gr_multiply_ff.cc b/gnuradio-core/src/lib/general/gr_multiply_ff.cc
index f764a71e8f..bb7bd07550 100644
--- a/gnuradio-core/src/lib/general/gr_multiply_ff.cc
+++ b/gnuradio-core/src/lib/general/gr_multiply_ff.cc
@@ -42,7 +42,7 @@ gr_multiply_ff::gr_multiply_ff (size_t vlen)
{
const int alignment_multiple =
volk_get_alignment() / sizeof(float);
- set_alignment(alignment_multiple);
+ set_alignment(std::max(1,alignment_multiple));
}
int
diff --git a/gnuradio-core/src/lib/general/gr_pack_k_bits_bb.cc b/gnuradio-core/src/lib/general/gr_pack_k_bits_bb.cc
new file mode 100644
index 0000000000..0ea0c9e388
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pack_k_bits_bb.cc
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pack_k_bits_bb.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <iostream>
+
+gr_pack_k_bits_bb_sptr gr_make_pack_k_bits_bb(unsigned k)
+{
+ return gnuradio::get_initial_sptr(new gr_pack_k_bits_bb(k));
+}
+
+
+gr_pack_k_bits_bb::gr_pack_k_bits_bb (unsigned k)
+ : gr_sync_decimator("pack_k_bits_bb",
+ gr_make_io_signature (1, 1, sizeof(unsigned char)),
+ gr_make_io_signature (1, 1, sizeof(unsigned char)),
+ k),
+ d_k (k)
+{
+ if (d_k == 0)
+ throw std::out_of_range("interpolation must be > 0");
+}
+
+gr_pack_k_bits_bb::~gr_pack_k_bits_bb()
+{
+}
+
+int
+gr_pack_k_bits_bb::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (const unsigned char *)input_items[0];
+ unsigned char *out = (unsigned char *)output_items[0];
+
+ for(int i = 0; i < noutput_items; i++) {
+ out[i] = 0x00;
+ for(unsigned int j = 0; j < d_k; j++) {
+ out[i] |= (0x01 & in[i*d_k+j])<<(d_k-j-1);
+ }
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_diff_phasor_cc.h b/gnuradio-core/src/lib/general/gr_pack_k_bits_bb.h
index 21c4f616d5..8e1508c78b 100644
--- a/gnuradio-core/src/lib/general/gr_diff_phasor_cc.h
+++ b/gnuradio-core/src/lib/general/gr_pack_k_bits_bb.h
@@ -1,49 +1,52 @@
/* -*- c++ -*- */
/*
- * Copyright 2006 Free Software Foundation, Inc.
- *
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
* This file is part of GNU Radio
- *
+ *
* GNU Radio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
- *
+ *
* GNU Radio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Radio; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
-#ifndef INCLUDED_GR_DIFF_PHASOR_CC_H
-#define INCLUDED_GR_DIFF_PHASOR_CC_H
+#ifndef INCLUDED_GR_PACK_K_BITS_BB_H
+#define INCLUDED_GR_PACK_K_BITS_BB_H
#include <gr_core_api.h>
-#include <gr_sync_block.h>
+#include <gr_sync_decimator.h>
-/*!
- * \brief Please fix my documentation!
- * \ingroup misc
- */
-class gr_diff_phasor_cc;
-typedef boost::shared_ptr<gr_diff_phasor_cc> gr_diff_phasor_cc_sptr;
-
-GR_CORE_API gr_diff_phasor_cc_sptr gr_make_diff_phasor_cc ();
+class gr_pack_k_bits_bb;
+typedef boost::shared_ptr<gr_pack_k_bits_bb> gr_pack_k_bits_bb_sptr;
+GR_CORE_API gr_pack_k_bits_bb_sptr gr_make_pack_k_bits_bb (unsigned k);
+class gr_pack_k_bits_bb;
-class GR_CORE_API gr_diff_phasor_cc : public gr_sync_block
+/*!
+ * \brief Converts a stream of bytes with 1 bit in the LSB to a byte with k relevent bits.
+ * \ingroup converter_blk
+ */
+class GR_CORE_API gr_pack_k_bits_bb : public gr_sync_decimator
{
- friend GR_CORE_API gr_diff_phasor_cc_sptr gr_make_diff_phasor_cc ();
+ private:
+ friend GR_CORE_API gr_pack_k_bits_bb_sptr gr_make_pack_k_bits_bb (unsigned k);
- gr_diff_phasor_cc (); //constructor
+ gr_pack_k_bits_bb (unsigned k);
+ unsigned d_k; // number of relevent bits to pack from k input bytes
+
public:
- ~gr_diff_phasor_cc(); //destructor
+ ~gr_pack_k_bits_bb ();
int work (int noutput_items,
gr_vector_const_void_star &input_items,
diff --git a/gnuradio-core/src/lib/general/gr_diff_phasor_cc.i b/gnuradio-core/src/lib/general/gr_pack_k_bits_bb.i
index 8aecd5cc77..6ae2095ec7 100644
--- a/gnuradio-core/src/lib/general/gr_diff_phasor_cc.i
+++ b/gnuradio-core/src/lib/general/gr_pack_k_bits_bb.i
@@ -1,34 +1,34 @@
/* -*- c++ -*- */
/*
- * Copyright 2006 Free Software Foundation, Inc.
- *
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
* This file is part of GNU Radio
- *
+ *
* GNU Radio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
- *
+ *
* GNU Radio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Radio; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
-GR_SWIG_BLOCK_MAGIC(gr,diff_phasor_cc)
+GR_SWIG_BLOCK_MAGIC(gr,pack_k_bits_bb)
-gr_diff_phasor_cc_sptr gr_make_diff_phasor_cc ();
+gr_pack_k_bits_bb_sptr gr_make_pack_k_bits_bb (int k) throw(std::exception);
-class gr_diff_phasor_cc : public gr_sync_block
+class gr_pack_k_bits_bb : public gr_sync_decimator
{
private:
- gr_diff_phasor_cc ();
+ gr_pack_k_bits_bb (int k);
public:
- ~gr_diff_phasor_cc();
+ ~gr_pack_k_bits_bb ();
};
diff --git a/gnuradio-core/src/lib/general/gr_packet_sink.cc b/gnuradio-core/src/lib/general/gr_packet_sink.cc
deleted file mode 100644
index 19a8c5fc20..0000000000
--- a/gnuradio-core/src/lib/general/gr_packet_sink.cc
+++ /dev/null
@@ -1,207 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2010 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gr_packet_sink.h>
-#include <gr_io_signature.h>
-#include <cstdio>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdexcept>
-#include <gr_count_bits.h>
-#include <string.h>
-
-#define VERBOSE 0
-
-static const int DEFAULT_THRESHOLD = 12; // detect access code with up to DEFAULT_THRESHOLD bits wrong
-
-inline void
-gr_packet_sink::enter_search()
-{
- if (VERBOSE)
- fprintf(stderr, "@ enter_search\n");
-
- d_state = STATE_SYNC_SEARCH;
- d_shift_reg = 0;
-}
-
-inline void
-gr_packet_sink::enter_have_sync()
-{
- if (VERBOSE)
- fprintf(stderr, "@ enter_have_sync\n");
-
- d_state = STATE_HAVE_SYNC;
- d_header = 0;
- d_headerbitlen_cnt = 0;
-}
-
-inline void
-gr_packet_sink::enter_have_header(int payload_len)
-{
- if (VERBOSE)
- fprintf(stderr, "@ enter_have_header (payload_len = %d)\n", payload_len);
-
- d_state = STATE_HAVE_HEADER;
- d_packetlen = payload_len;
- d_packetlen_cnt = 0;
- d_packet_byte = 0;
- d_packet_byte_index = 0;
-}
-
-gr_packet_sink_sptr
-gr_make_packet_sink (const std::vector<unsigned char>& sync_vector,
- gr_msg_queue_sptr target_queue, int threshold)
-{
- return gnuradio::get_initial_sptr(new gr_packet_sink (sync_vector, target_queue, threshold));
-}
-
-
-gr_packet_sink::gr_packet_sink (const std::vector<unsigned char>& sync_vector,
- gr_msg_queue_sptr target_queue, int threshold)
- : gr_sync_block ("packet_sink",
- gr_make_io_signature (1, 1, sizeof(float)),
- gr_make_io_signature (0, 0, 0)),
- d_target_queue(target_queue), d_threshold(threshold == -1 ? DEFAULT_THRESHOLD : threshold)
-{
- d_sync_vector = 0;
- for(int i=0;i<8;i++){
- d_sync_vector <<= 8;
- d_sync_vector |= sync_vector[i];
- }
-
- enter_search();
-}
-
-gr_packet_sink::~gr_packet_sink ()
-{
-}
-
-int
-gr_packet_sink::work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- float *inbuf = (float *) input_items[0];
- int count=0;
-
- if (VERBOSE)
- fprintf(stderr,">>> Entering state machine\n"),fflush(stderr);
-
- while (count<noutput_items) {
- switch(d_state) {
-
- case STATE_SYNC_SEARCH: // Look for sync vector
- if (VERBOSE)
- fprintf(stderr,"SYNC Search, noutput=%d\n",noutput_items),fflush(stderr);
-
- while (count < noutput_items) {
- if(slice(inbuf[count++]))
- d_shift_reg = (d_shift_reg << 1) | 1;
- else
- d_shift_reg = d_shift_reg << 1;
-
- // Compute popcnt of putative sync vector
- if(gr_count_bits64 (d_shift_reg ^ d_sync_vector) <= d_threshold) {
- // Found it, set up for header decode
- enter_have_sync();
- break;
- }
- }
- break;
-
- case STATE_HAVE_SYNC:
- if (VERBOSE)
- fprintf(stderr,"Header Search bitcnt=%d, header=0x%08x\n", d_headerbitlen_cnt, d_header),
- fflush(stderr);
-
- while (count < noutput_items) { // Shift bits one at a time into header
- if(slice(inbuf[count++]))
- d_header = (d_header << 1) | 1;
- else
- d_header = d_header << 1;
-
- if (++d_headerbitlen_cnt == HEADERBITLEN) {
-
- if (VERBOSE)
- fprintf(stderr, "got header: 0x%08x\n", d_header);
-
- // we have a full header, check to see if it has been received properly
- if (header_ok()){
- int payload_len = header_payload_len();
- if (payload_len <= MAX_PKT_LEN) // reasonable?
- enter_have_header(payload_len); // yes.
- else
- enter_search(); // no.
- }
- else
- enter_search(); // no.
- break; // we're in a new state
- }
- }
- break;
-
- case STATE_HAVE_HEADER:
- if (VERBOSE)
- fprintf(stderr,"Packet Build\n"),fflush(stderr);
-
- while (count < noutput_items) { // shift bits into bytes of packet one at a time
- if(slice(inbuf[count++]))
- d_packet_byte = (d_packet_byte << 1) | 1;
- else
- d_packet_byte = d_packet_byte << 1;
-
- if (d_packet_byte_index++ == 7) { // byte is full so move to next byte
- d_packet[d_packetlen_cnt++] = d_packet_byte;
- d_packet_byte_index = 0;
-
- if (d_packetlen_cnt == d_packetlen){ // packet is filled
-
- // build a message
- gr_message_sptr msg = gr_make_message(0, 0, 0, d_packetlen_cnt);
- memcpy(msg->msg(), d_packet, d_packetlen_cnt);
-
- d_target_queue->insert_tail(msg); // send it
- msg.reset(); // free it up
-
- enter_search();
- break;
- }
- }
- }
- break;
-
- default:
- assert(0);
-
- } // switch
-
- } // while
-
- return noutput_items;
-}
-
diff --git a/gnuradio-core/src/lib/general/gr_packet_sink.h b/gnuradio-core/src/lib/general/gr_packet_sink.h
deleted file mode 100644
index b4cb0b0f6e..0000000000
--- a/gnuradio-core/src/lib/general/gr_packet_sink.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2005 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef INCLUDED_GR_PACKET_SINK_H
-#define INCLUDED_GR_PACKET_SINK_H
-
-#include <gr_core_api.h>
-#include <gr_sync_block.h>
-#include <gr_msg_queue.h>
-
-class gr_packet_sink;
-typedef boost::shared_ptr<gr_packet_sink> gr_packet_sink_sptr;
-
-GR_CORE_API gr_packet_sink_sptr
-gr_make_packet_sink (const std::vector<unsigned char>& sync_vector,
- gr_msg_queue_sptr target_queue,
- int threshold = -1 // -1 -> use default
- );
-/*!
- * \brief process received bits looking for packet sync, header, and process bits into packet
- * \ingroup sink_blk
- */
-class GR_CORE_API gr_packet_sink : public gr_sync_block
-{
- friend GR_CORE_API gr_packet_sink_sptr
- gr_make_packet_sink (const std::vector<unsigned char>& sync_vector,
- gr_msg_queue_sptr target_queue,
- int threshold);
-
- private:
- enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER};
-
- static const int MAX_PKT_LEN = 4096;
- static const int HEADERBITLEN = 32;
-
- gr_msg_queue_sptr d_target_queue; // where to send the packet when received
- unsigned long long d_sync_vector; // access code to locate start of packet
- unsigned int d_threshold; // how many bits may be wrong in sync vector
-
- state_t d_state;
-
- unsigned long long d_shift_reg; // used to look for sync_vector
-
- unsigned int d_header; // header bits
- int d_headerbitlen_cnt; // how many so far
-
- unsigned char d_packet[MAX_PKT_LEN]; // assembled payload
- unsigned char d_packet_byte; // byte being assembled
- int d_packet_byte_index; // which bit of d_packet_byte we're working on
- int d_packetlen; // length of packet
- int d_packetlen_cnt; // how many so far
-
- protected:
- gr_packet_sink(const std::vector<unsigned char>& sync_vector,
- gr_msg_queue_sptr target_queue,
- int threshold);
-
- void enter_search();
- void enter_have_sync();
- void enter_have_header(int payload_len);
-
- int slice(float x) { return x > 0 ? 1 : 0; }
-
- bool header_ok()
- {
- // confirm that two copies of header info are identical
- return ((d_header >> 16) ^ (d_header & 0xffff)) == 0;
- }
-
- int header_payload_len()
- {
- // header consists of two 16-bit shorts in network byte order
- int t = (d_header >> 16) & 0xffff;
- return t;
- }
-
- public:
- ~gr_packet_sink();
-
- int work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-
-
- //! return true if we detect carrier
- bool carrier_sensed() const
- {
- return d_state != STATE_SYNC_SEARCH;
- }
-
-};
-
-#endif /* INCLUDED_GR_PACKET_SINK_H */
diff --git a/gnuradio-core/src/lib/general/gr_pn_correlator_cc.cc b/gnuradio-core/src/lib/general/gr_pn_correlator_cc.cc
deleted file mode 100644
index 818e48c34b..0000000000
--- a/gnuradio-core/src/lib/general/gr_pn_correlator_cc.cc
+++ /dev/null
@@ -1,77 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,2010 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gr_pn_correlator_cc.h>
-#include <gr_io_signature.h>
-
-gr_pn_correlator_cc_sptr
-gr_make_pn_correlator_cc(int degree, int mask, int seed)
-{
- return gnuradio::get_initial_sptr(new gr_pn_correlator_cc(degree, mask, seed));
-}
-
-gr_pn_correlator_cc::gr_pn_correlator_cc(int degree, int mask, int seed)
- : gr_sync_decimator ("pn_correlator_cc",
- gr_make_io_signature (1, 1, sizeof(gr_complex)),
- gr_make_io_signature (1, 1, sizeof(gr_complex)),
- (unsigned int)((1ULL << degree)-1)) // PN code length
-{
- d_len = (unsigned int)((1ULL << degree)-1);
- if (mask == 0)
- mask = gri_glfsr::glfsr_mask(degree);
- d_reference = new gri_glfsr(mask, seed);
- for (int i = 0; i < d_len; i++) // initialize to last value in sequence
- d_pn = 2.0*d_reference->next_bit()-1.0;
-}
-
-gr_pn_correlator_cc::~gr_pn_correlator_cc()
-{
- delete d_reference;
-}
-
-int
-gr_pn_correlator_cc::work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- const gr_complex *in = (const gr_complex *) input_items[0];
- gr_complex *out = (gr_complex *) output_items[0];
- gr_complex sum;
-
- for (int i = 0; i < noutput_items; i++) {
- sum = 0.0;
-
- for (int j = 0; j < d_len; j++) {
- if (j != 0) // retard PN generator one sample per period
- d_pn = 2.0*d_reference->next_bit()-1.0; // no conditionals
- sum += *in++ * d_pn;
- }
-
- *out++ = sum*gr_complex(1.0/d_len, 0.0);
- }
-
- return noutput_items;
-}
diff --git a/gnuradio-core/src/lib/general/gr_pn_correlator_cc.h b/gnuradio-core/src/lib/general/gr_pn_correlator_cc.h
deleted file mode 100644
index 69bd2c502f..0000000000
--- a/gnuradio-core/src/lib/general/gr_pn_correlator_cc.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef INCLUDED_GR_PN_CORRELATOR_CC_H
-#define INCLUDED_GR_PN_CORRELATOR_CC_H
-
-#include <gr_core_api.h>
-#include <gr_sync_decimator.h>
-#include <gri_glfsr.h>
-
-class gr_pn_correlator_cc;
-typedef boost::shared_ptr<gr_pn_correlator_cc> gr_pn_correlator_cc_sptr;
-
-GR_CORE_API gr_pn_correlator_cc_sptr
-gr_make_pn_correlator_cc(int degree, int mask=0, int seed=1);
-/*!
- * \brief PN code sequential search correlator
- *
- * \ingroup sync_blk
- * Receives complex baseband signal, outputs complex correlation against
- * reference PN code, one sample per PN code period
- */
-
-class GR_CORE_API gr_pn_correlator_cc : public gr_sync_decimator
-{
- friend GR_CORE_API gr_pn_correlator_cc_sptr gr_make_pn_correlator_cc(int degree, int mask, int seed);
-
- int d_len;
- float d_pn;
- gri_glfsr *d_reference;
-
- protected:
- gr_pn_correlator_cc(int degree, int mask, int seed);
-
- public:
- virtual int work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-
- ~gr_pn_correlator_cc();
-};
-
-#endif /* INCLUDED_GR_PN_CORRELATOR_CC_H */
diff --git a/gnuradio-core/src/lib/general/gr_pn_correlator_cc.i b/gnuradio-core/src/lib/general/gr_pn_correlator_cc.i
deleted file mode 100644
index e992f33a7f..0000000000
--- a/gnuradio-core/src/lib/general/gr_pn_correlator_cc.i
+++ /dev/null
@@ -1,32 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-GR_SWIG_BLOCK_MAGIC(gr,pn_correlator_cc)
-
-gr_pn_correlator_cc_sptr
-gr_make_pn_correlator_cc(int degree, int mask=0, int seed=1);
-
-class gr_pn_correlator_cc : public gr_sync_decimator
-{
- protected:
- gr_pn_correlator_cc();
-};
diff --git a/gnuradio-core/src/lib/general/gr_probe_density_b.cc b/gnuradio-core/src/lib/general/gr_probe_density_b.cc
deleted file mode 100644
index 31661780af..0000000000
--- a/gnuradio-core/src/lib/general/gr_probe_density_b.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008,2010 Free Software Foundation, Inc.
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gr_probe_density_b.h>
-#include <gr_io_signature.h>
-#include <stdexcept>
-#include <iostream>
-
-gr_probe_density_b_sptr
-gr_make_probe_density_b(double alpha)
-{
- return gnuradio::get_initial_sptr(new gr_probe_density_b(alpha));
-}
-
-gr_probe_density_b::gr_probe_density_b(double alpha)
- : gr_sync_block("density_b",
- gr_make_io_signature(1, 1, sizeof(char)),
- gr_make_io_signature(0, 0, 0))
-{
- set_alpha(alpha);
- d_density = 1.0;
-}
-
-gr_probe_density_b::~gr_probe_density_b()
-{
-}
-
-int
-gr_probe_density_b::work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- const char *in = (const char *)input_items[0];
-
- for (int i = 0; i < noutput_items; i++)
- d_density = d_alpha*(double)in[i] + d_beta*d_density;
-
- return noutput_items;
-}
-
-void
-gr_probe_density_b::set_alpha(double alpha)
-{
- d_alpha = alpha;
- d_beta = 1.0-d_alpha;
-}
-
diff --git a/gnuradio-core/src/lib/general/gr_probe_density_b.h b/gnuradio-core/src/lib/general/gr_probe_density_b.h
deleted file mode 100644
index ab84a63a96..0000000000
--- a/gnuradio-core/src/lib/general/gr_probe_density_b.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-#ifndef INCLUDED_GR_PROBE_DENSITY_B_H
-#define INCLUDED_GR_PROBE_DENSITY_B_H
-
-#include <gr_core_api.h>
-#include <gr_sync_block.h>
-
-class gr_probe_density_b;
-
-typedef boost::shared_ptr<gr_probe_density_b> gr_probe_density_b_sptr;
-
-GR_CORE_API gr_probe_density_b_sptr gr_make_probe_density_b(double alpha);
-
-/*!
- * This block maintains a running average of the input stream and
- * makes it available as an accessor function. The input stream
- * is type unsigned char.
- *
- * If you send this block a stream of unpacked bytes, it will tell
- * you what the bit density is.
- *
- * \param alpha Average filter constant
- *
- */
-
-class GR_CORE_API gr_probe_density_b : public gr_sync_block
-{
-private:
- friend GR_CORE_API gr_probe_density_b_sptr gr_make_probe_density_b(double alpha);
-
- double d_alpha;
- double d_beta;
- double d_density;
-
- gr_probe_density_b(double alpha);
-
-public:
- ~gr_probe_density_b();
-
- /*!
- * \brief Returns the current density value
- */
- double density() const { return d_density; }
-
- /*!
- * \brief Set the average filter constant
- */
- void set_alpha(double alpha);
-
- int work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-};
-
-#endif /* INCLUDED_GR_PROBE_DENSITY_B_H */
diff --git a/gnuradio-core/src/lib/general/gr_scrambler_bb.cc b/gnuradio-core/src/lib/general/gr_scrambler_bb.cc
deleted file mode 100644
index 31eb192077..0000000000
--- a/gnuradio-core/src/lib/general/gr_scrambler_bb.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008,2010 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gr_scrambler_bb.h>
-#include <gr_io_signature.h>
-
-gr_scrambler_bb_sptr
-gr_make_scrambler_bb(int mask, int seed, int len)
-{
- return gnuradio::get_initial_sptr(new gr_scrambler_bb(mask, seed, len));
-}
-
-gr_scrambler_bb::gr_scrambler_bb(int mask, int seed, int len)
- : gr_sync_block("scrambler_bb",
- gr_make_io_signature (1, 1, sizeof (unsigned char)),
- gr_make_io_signature (1, 1, sizeof (unsigned char))),
- d_lfsr(mask, seed, len)
-{
-}
-
-int
-gr_scrambler_bb::work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- const unsigned char *in = (const unsigned char *) input_items[0];
- unsigned char *out = (unsigned char *) output_items[0];
-
- for (int i = 0; i < noutput_items; i++)
- out[i] = d_lfsr.next_bit_scramble(in[i]);
-
- return noutput_items;
-}
diff --git a/gnuradio-core/src/lib/general/gr_scrambler_bb.h b/gnuradio-core/src/lib/general/gr_scrambler_bb.h
deleted file mode 100644
index edb429e0a0..0000000000
--- a/gnuradio-core/src/lib/general/gr_scrambler_bb.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-#ifndef INCLUDED_GR_SCRAMBLER_BB_H
-#define INCLUDED_GR_SCRAMBLER_BB_H
-
-#include <gr_core_api.h>
-#include <gr_sync_block.h>
-#include "gri_lfsr.h"
-
-class gr_scrambler_bb;
-typedef boost::shared_ptr<gr_scrambler_bb> gr_scrambler_bb_sptr;
-
-GR_CORE_API gr_scrambler_bb_sptr gr_make_scrambler_bb(int mask, int seed, int len);
-
-/*!
- * Scramble an input stream using an LFSR. This block works on the LSB only
- * of the input data stream, i.e., on an "unpacked binary" stream, and
- * produces the same format on its output.
- *
- * \param mask Polynomial mask for LFSR
- * \param seed Initial shift register contents
- * \param len Shift register length
- *
- * \ingroup coding_blk
- */
-
-class GR_CORE_API gr_scrambler_bb : public gr_sync_block
-{
- friend GR_CORE_API gr_scrambler_bb_sptr gr_make_scrambler_bb(int mask, int seed, int len);
-
- gri_lfsr d_lfsr;
-
- gr_scrambler_bb(int mask, int seed, int len);
-
-public:
- int work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-};
-
-#endif /* INCLUDED_GR_SCRAMBLER_BB_H */
diff --git a/gnuradio-core/src/lib/general/gr_scrambler_bb.i b/gnuradio-core/src/lib/general/gr_scrambler_bb.i
deleted file mode 100644
index a7ef7b364f..0000000000
--- a/gnuradio-core/src/lib/general/gr_scrambler_bb.i
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-GR_SWIG_BLOCK_MAGIC(gr,scrambler_bb);
-
-gr_scrambler_bb_sptr gr_make_scrambler_bb(int mask, int seed, int len);
-
-class gr_scrambler_bb : public gr_sync_block
-{
-private:
- gr_scrambler_bb(int mask, int seed, int len);
-};
diff --git a/gnuradio-core/src/lib/general/gr_short_to_char.cc b/gnuradio-core/src/lib/general/gr_short_to_char.cc
index 9d6c41406e..8c146a351d 100644
--- a/gnuradio-core/src/lib/general/gr_short_to_char.cc
+++ b/gnuradio-core/src/lib/general/gr_short_to_char.cc
@@ -42,7 +42,7 @@ gr_short_to_char::gr_short_to_char (size_t vlen)
{
const int alignment_multiple =
volk_get_alignment() / sizeof(char);
- set_alignment(alignment_multiple);
+ set_alignment(std::max(1,alignment_multiple));
}
int
diff --git a/gnuradio-core/src/lib/general/gr_short_to_float.cc b/gnuradio-core/src/lib/general/gr_short_to_float.cc
index 960cf644d1..093d6024fa 100644
--- a/gnuradio-core/src/lib/general/gr_short_to_float.cc
+++ b/gnuradio-core/src/lib/general/gr_short_to_float.cc
@@ -42,7 +42,7 @@ gr_short_to_float::gr_short_to_float (size_t vlen, float scale)
{
const int alignment_multiple =
volk_get_alignment() / sizeof(float);
- set_alignment(alignment_multiple);
+ set_alignment(std::max(1,alignment_multiple));
}
float
diff --git a/gnuradio-core/src/lib/general/gr_simple_framer.cc b/gnuradio-core/src/lib/general/gr_simple_framer.cc
deleted file mode 100644
index 506603bb71..0000000000
--- a/gnuradio-core/src/lib/general/gr_simple_framer.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2010 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gr_simple_framer.h>
-#include <gr_simple_framer_sync.h>
-#include <gr_io_signature.h>
-#include <assert.h>
-#include <stdexcept>
-#include <string.h>
-
-
-gr_simple_framer_sptr
-gr_make_simple_framer (int payload_bytesize)
-{
- return gnuradio::get_initial_sptr(new gr_simple_framer (payload_bytesize));
-}
-
-gr_simple_framer::gr_simple_framer (int payload_bytesize)
- : gr_block ("simple_framer",
- gr_make_io_signature (1, 1, sizeof (unsigned char)),
- gr_make_io_signature (1, 1, sizeof (unsigned char))),
- d_seqno (0), d_payload_bytesize (payload_bytesize),
- d_input_block_size (payload_bytesize),
- d_output_block_size (payload_bytesize + GRSF_OVERHEAD)
-{
- set_output_multiple (d_output_block_size);
-}
-
-void
-gr_simple_framer::forecast (int noutput_items, gr_vector_int &ninput_items_required)
-{
- assert (noutput_items % d_output_block_size == 0);
-
- int nblocks = noutput_items / d_output_block_size;
- int input_required = nblocks * d_input_block_size;
-
- unsigned ninputs = ninput_items_required.size();
- for (unsigned int i = 0; i < ninputs; i++)
- ninput_items_required[i] = input_required;
-}
-
-int
-gr_simple_framer::general_work (int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- const unsigned char *in = (const unsigned char *) input_items[0];
- unsigned char *out = (unsigned char *) output_items[0];
-
- int n = 0;
- int nblocks = 0;
-
- memset (out, 0x55, noutput_items);
-
- while (n < noutput_items){
- out[0] = (GRSF_SYNC >> 56) & 0xff;
- out[1] = (GRSF_SYNC >> 48) & 0xff;
- out[2] = (GRSF_SYNC >> 40) & 0xff;
- out[3] = (GRSF_SYNC >> 32) & 0xff;
- out[4] = (GRSF_SYNC >> 24) & 0xff;
- out[5] = (GRSF_SYNC >> 16) & 0xff;
- out[6] = (GRSF_SYNC >> 8) & 0xff;
- out[7] = (GRSF_SYNC >> 0) & 0xff;
- out[8] = d_seqno++;
-
- memcpy (&out[9], in, d_input_block_size);
- in += d_input_block_size;
- out += d_output_block_size;
- n += d_output_block_size;
- nblocks++;
- }
-
- assert (n == noutput_items);
-
- consume_each (nblocks * d_input_block_size);
- return n;
-}
diff --git a/gnuradio-core/src/lib/general/gr_simple_framer.h b/gnuradio-core/src/lib/general/gr_simple_framer.h
deleted file mode 100644
index 76a4b7baba..0000000000
--- a/gnuradio-core/src/lib/general/gr_simple_framer.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef INCLUDED_GR_SIMPLE_FRAMER_H
-#define INCLUDED_GR_SIMPLE_FRAMER_H
-
-#include <gr_core_api.h>
-#include <gr_block.h>
-
-class gr_simple_framer;
-typedef boost::shared_ptr<gr_simple_framer> gr_simple_framer_sptr;
-
-GR_CORE_API gr_simple_framer_sptr gr_make_simple_framer (int payload_bytesize);
-
-/*!
- * \brief add sync field, seq number and command field to payload
- * \ingroup sync_blk
- */
-class GR_CORE_API gr_simple_framer : public gr_block
-{
- int d_seqno;
- int d_payload_bytesize;
- int d_input_block_size; // bytes
- int d_output_block_size; // bytes
-
- friend GR_CORE_API gr_simple_framer_sptr gr_make_simple_framer (int payload_bytesize);
- gr_simple_framer (int payload_bytesize);
-
- public:
- void forecast (int noutput_items,
- gr_vector_int &ninput_items_required);
-
- int general_work (int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-};
-
-
-#endif /* INCLUDED_GR_SIMPLE_FRAMER_H */
diff --git a/gnuradio-core/src/lib/general/gr_simple_framer.i b/gnuradio-core/src/lib/general/gr_simple_framer.i
deleted file mode 100644
index c13ead87bf..0000000000
--- a/gnuradio-core/src/lib/general/gr_simple_framer.i
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-GR_SWIG_BLOCK_MAGIC(gr,simple_framer);
-
-gr_simple_framer_sptr gr_make_simple_framer (int payload_bytesize);
-
-class gr_simple_framer : public gr_block
-{
- private:
- gr_simple_framer (int payload_bytesize);
-};
diff --git a/gnuradio-core/src/lib/general/gr_tag_debug.cc b/gnuradio-core/src/lib/general/gr_tag_debug.cc
new file mode 100644
index 0000000000..c4031f438d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_tag_debug.cc
@@ -0,0 +1,100 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_tag_debug.h>
+#include <gr_io_signature.h>
+#include <iostream>
+#include <iomanip>
+
+gr_tag_debug_sptr
+gr_make_tag_debug(size_t sizeof_stream_item, const std::string &name)
+{
+ return gnuradio::get_initial_sptr
+ (new gr_tag_debug(sizeof_stream_item, name));
+}
+
+gr_tag_debug::gr_tag_debug(size_t sizeof_stream_item, const std::string &name)
+ : gr_sync_block("tag_debug",
+ gr_make_io_signature(1, -1, sizeof_stream_item),
+ gr_make_io_signature(0, 0, 0)),
+ d_name(name), d_display(true)
+{
+}
+
+std::vector<gr_tag_t>
+gr_tag_debug::current_tags()
+{
+ gruel::scoped_lock l(d_mutex);
+ return d_tags;
+}
+
+void
+gr_tag_debug::set_display(bool d)
+{
+ gruel::scoped_lock l(d_mutex);
+ d_display = d;
+}
+
+int
+gr_tag_debug::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ gruel::scoped_lock l(d_mutex);
+
+ if(d_display) {
+ std::cout << std::endl
+ << "----------------------------------------------------------------------";
+ std::cout << std::endl << "Tag Debug: " << d_name << std::endl;
+ }
+
+ uint64_t abs_N, end_N;
+ for(size_t i = 0; i < input_items.size(); i++) {
+ abs_N = nitems_read(i);
+ end_N = abs_N + (uint64_t)(noutput_items);
+
+ d_tags.clear();
+ get_tags_in_range(d_tags, i, abs_N, end_N);
+
+ if(d_display) {
+ std::cout << "Input Stream: " << i << std::endl;
+ for(d_tags_itr = d_tags.begin(); d_tags_itr != d_tags.end(); d_tags_itr++) {
+ std::cout << std::setw(10) << "Offset: " << d_tags_itr->offset
+ << std::setw(10) << "Source: " << pmt::pmt_symbol_to_string(d_tags_itr->srcid)
+ << std::setw(10) << "Key: " << pmt::pmt_symbol_to_string(d_tags_itr->key)
+ << std::setw(10) << "Value: ";
+ pmt::pmt_print(d_tags_itr->value);
+ }
+ }
+ }
+
+ if(d_display) {
+ std::cout << "----------------------------------------------------------------------";
+ std::cout << std::endl;
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_tag_debug.h b/gnuradio-core/src/lib/general/gr_tag_debug.h
new file mode 100644
index 0000000000..57578884a8
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_tag_debug.h
@@ -0,0 +1,85 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_TAG_DEBUG_H
+#define INCLUDED_GR_TAG_DEBUG_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gruel/thread.h>
+#include <stddef.h>
+
+class gr_tag_debug;
+typedef boost::shared_ptr<gr_tag_debug> gr_tag_debug_sptr;
+
+GR_CORE_API gr_tag_debug_sptr
+gr_make_tag_debug(size_t sizeof_stream_item, const std::string &name);
+
+/*!
+ * \brief Bit bucket that prints out any tag received.
+ * \ingroup sink_blk
+ *
+ * This block collects all tags sent to it on all input ports and
+ * displays them to stdout in a formatted way. The \p name parameter
+ * is used to identify which debug sink generated the tag, so when
+ * connecting a block to this debug sink, an appropriate name is
+ * something that identifies the input block.
+ *
+ * This block otherwise acts as a NULL sink in that items from the
+ * input stream are ignored. It is designed to be able to attach to
+ * any block and watch all tags streaming out of that block for
+ * debugging purposes.
+ *
+ * The tags from the last call to this work function are stored and
+ * can be retrieved using the function 'current_tags'.
+ */
+class GR_CORE_API gr_tag_debug : public gr_sync_block
+{
+ private:
+ friend GR_CORE_API gr_tag_debug_sptr
+ gr_make_tag_debug(size_t sizeof_stream_item, const std::string &name);
+ gr_tag_debug(size_t sizeof_stream_item, const std::string &name);
+
+ std::string d_name;
+ std::vector<gr_tag_t> d_tags;
+ std::vector<gr_tag_t>::iterator d_tags_itr;
+ bool d_display;
+ gruel::mutex d_mutex;
+
+ public:
+ /*!
+ * \brief Returns a vector of gr_tag_t items as of the last call to
+ * work.
+ */
+ std::vector<gr_tag_t> current_tags();
+
+ /*!
+ * \brief Set the display of tags to stdout on/off.
+ */
+ void set_display(bool d);
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_TAG_DEBUG_H */
diff --git a/gnuradio-core/src/lib/general/gr_probe_density_b.i b/gnuradio-core/src/lib/general/gr_tag_debug.i
index ca65708af6..3af1bdcfef 100644
--- a/gnuradio-core/src/lib/general/gr_probe_density_b.i
+++ b/gnuradio-core/src/lib/general/gr_tag_debug.i
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -20,17 +20,16 @@
* Boston, MA 02110-1301, USA.
*/
-GR_SWIG_BLOCK_MAGIC(gr,probe_density_b);
+GR_SWIG_BLOCK_MAGIC(gr,tag_debug)
-gr_probe_density_b_sptr gr_make_probe_density_b(double alpha);
+%include <gr_tags.i>
-class gr_probe_density_b : public gr_sync_block
+gr_tag_debug_sptr
+gr_make_tag_debug(size_t sizeof_stream_item, const std::string &name);
+
+class gr_tag_debug : public gr_sync_block
{
public:
- double density() const;
-
- void set_alpha(double alpha);
-
-private:
- gr_probe_density_b();
+ std::vector<gr_tag_t> current_tags();
+ void set_display(bool d);
};
diff --git a/gnuradio-core/src/lib/general/gr_vector_map.cc b/gnuradio-core/src/lib/general/gr_vector_map.cc
new file mode 100644
index 0000000000..2a13efb06d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vector_map.cc
@@ -0,0 +1,117 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_vector_map.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+std::vector<int>
+get_in_sizeofs(size_t item_size, std::vector<size_t> in_vlens)
+{
+ std::vector<int> in_sizeofs;
+ for(unsigned int i = 0; i < in_vlens.size(); i++) {
+ in_sizeofs.push_back(in_vlens[i]*item_size);
+ }
+ return in_sizeofs;
+}
+
+std::vector<int>
+get_out_sizeofs(size_t item_size,
+ std::vector< std::vector< std::vector<size_t> > > mapping)
+{
+ std::vector<int> out_sizeofs;
+ for(unsigned int i = 0; i < mapping.size(); i++) {
+ out_sizeofs.push_back(mapping[i].size()*item_size);
+ }
+ return out_sizeofs;
+}
+
+gr_vector_map_sptr
+gr_make_vector_map (size_t item_size, std::vector<size_t> in_vlens,
+ std::vector< std::vector< std::vector<size_t> > > mapping)
+{
+ return gnuradio::get_initial_sptr(new gr_vector_map(item_size,
+ in_vlens,
+ mapping));
+}
+
+gr_vector_map::gr_vector_map(size_t item_size, std::vector<size_t> in_vlens,
+ std::vector< std::vector< std::vector<size_t> > > mapping)
+ : gr_sync_block("vector_map",
+ gr_make_io_signaturev(in_vlens.size(), in_vlens.size(),
+ get_in_sizeofs(item_size, in_vlens)),
+ gr_make_io_signaturev(mapping.size(), mapping.size(),
+ get_out_sizeofs(item_size, mapping))),
+ d_item_size(item_size), d_in_vlens(in_vlens)
+{
+ set_mapping(mapping);
+}
+
+void
+gr_vector_map::set_mapping(std::vector< std::vector< std::vector<size_t> > > mapping) {
+ // Make sure the contents of the mapping vectors are possible.
+ for(unsigned int i=0; i<mapping.size(); i++) {
+ for(unsigned int j=0; j<mapping[i].size(); j++) {
+ if(mapping[i][j].size() != 2) {
+ throw std::runtime_error("Mapping must be of the form (out_mapping_stream1, out_mapping_stream2, ...), where out_mapping_stream1 is of the form (mapping_element1, mapping_element2, ...), where mapping_element1 is of the form (input_stream, input_element). This error is raised because a mapping_element vector does not contain exactly 2 items.");
+ }
+ unsigned int s = mapping[i][j][0];
+ unsigned int index = mapping[i][j][1];
+ if(s >= d_in_vlens.size()) {
+ throw std::runtime_error("Stream numbers in mapping must be less than the number of input streams.");
+ }
+ if((index < 0) || (index >= d_in_vlens[s])) {
+ throw std::runtime_error ("Indices in mapping must be greater than 0 and less than the input vector lengths.");
+ }
+ }
+ }
+ gruel::scoped_lock guard(d_mutex);
+ d_mapping = mapping;
+}
+
+int
+gr_vector_map::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const char **inv = (const char **) &input_items[0];
+ char **outv = (char **) &output_items[0];
+
+ for(unsigned int n = 0; n < (unsigned int)(noutput_items); n++) {
+ for(unsigned int i = 0; i < d_mapping.size(); i++) {
+ unsigned int out_vlen = d_mapping[i].size();
+ for(unsigned int j = 0; j < out_vlen; j++) {
+ unsigned int s = d_mapping[i][j][0];
+ unsigned int k = d_mapping[i][j][1];
+ memcpy(outv[i] + out_vlen*d_item_size*n +
+ d_item_size*j, inv[s] + d_in_vlens[s]*d_item_size*n +
+ k*d_item_size, d_item_size);
+ }
+ }
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_vector_map.h b/gnuradio-core/src/lib/general/gr_vector_map.h
new file mode 100644
index 0000000000..f5492b1e3a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vector_map.h
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_VECTOR_MAP_H
+#define INCLUDED_GR_VECTOR_MAP_H
+
+#include <vector>
+#include <gr_core_api.h>
+#include <gr_sync_interpolator.h>
+#include <gruel/thread.h>
+
+class gr_vector_map;
+typedef boost::shared_ptr<gr_vector_map> gr_vector_map_sptr;
+
+GR_CORE_API gr_vector_map_sptr
+gr_make_vector_map (size_t item_size, std::vector<size_t> in_vlens,
+ std::vector< std::vector< std::vector<size_t> > > mapping);
+
+/*!
+ * \brief Maps elements from a set of input vectors to a set of output vectors.
+ *
+ * If in[i] is the input vector in the i'th stream then the output
+ * vector in the j'th stream is:
+ *
+ * out[j][k] = in[mapping[j][k][0]][mapping[j][k][1]]
+ *
+ * That is mapping is of the form (out_stream1_mapping,
+ * out_stream2_mapping, ...) and out_stream1_mapping is of the form
+ * (element1_mapping, element2_mapping, ...) and element1_mapping is
+ * of the form (in_stream, in_element).
+ *
+ * \param item_size (integer) size of vector elements
+ *
+ * \param in_vlens (vector of integers) number of elements in each
+ * input vector
+ *
+ * \param mapping (vector of vectors of vectors of integers) how to
+ * map elements from input to output vectors
+ *
+ * \ingroup slicedice_blk
+ */
+class GR_CORE_API gr_vector_map : public gr_sync_block
+{
+ friend GR_CORE_API gr_vector_map_sptr
+ gr_make_vector_map(size_t item_size, std::vector<size_t> in_vlens,
+ std::vector< std::vector< std::vector<size_t> > > mapping);
+ size_t d_item_size;
+ std::vector<size_t> d_in_vlens;
+ std::vector< std::vector< std::vector<size_t> > > d_mapping;
+ gruel::mutex d_mutex; // mutex to protect set/work access
+
+ protected:
+ gr_vector_map(size_t item_size, std::vector<size_t> in_vlens,
+ std::vector< std::vector< std::vector<size_t> > > mapping);
+
+ public:
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ void set_mapping(std::vector< std::vector< std::vector<size_t> > > mapping);
+};
+
+#endif /* INCLUDED_GR_VECTOR_MAP_H */
diff --git a/gnuradio-core/src/lib/general/gr_bytes_to_syms.i b/gnuradio-core/src/lib/general/gr_vector_map.i
index 185e7cd290..e9fa3f27e5 100644
--- a/gnuradio-core/src/lib/general/gr_bytes_to_syms.i
+++ b/gnuradio-core/src/lib/general/gr_vector_map.i
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -20,11 +20,9 @@
* Boston, MA 02110-1301, USA.
*/
-GR_SWIG_BLOCK_MAGIC(gr,bytes_to_syms);
+GR_SWIG_BLOCK_MAGIC(gr, vector_map);
-gr_bytes_to_syms_sptr gr_make_bytes_to_syms ();
+%template() std::vector<size_t>;
+%template() std::vector< std::vector< std::vector<size_t> > >;
-class gr_bytes_to_syms : public gr_sync_interpolator
-{
- gr_bytes_to_syms ();
-};
+%include "gr_vector_map.h"
diff --git a/gnuradio-core/src/lib/general/gri_glfsr.cc b/gnuradio-core/src/lib/general/gri_glfsr.cc
deleted file mode 100644
index ba6951882b..0000000000
--- a/gnuradio-core/src/lib/general/gri_glfsr.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#include <gri_glfsr.h>
-#include <stdexcept>
-
-static int s_polynomial_masks[] = {
- 0x00000000,
- 0x00000001, // x^1 + 1
- 0x00000003, // x^2 + x^1 + 1
- 0x00000005, // x^3 + x^1 + 1
- 0x00000009, // x^4 + x^1 + 1
- 0x00000012, // x^5 + x^2 + 1
- 0x00000021, // x^6 + x^1 + 1
- 0x00000041, // x^7 + x^1 + 1
- 0x0000008E, // x^8 + x^4 + x^3 + x^2 + 1
- 0x00000108, // x^9 + x^4 + 1
- 0x00000204, // x^10 + x^4 + 1
- 0x00000402, // x^11 + x^2 + 1
- 0x00000829, // x^12 + x^6 + x^4 + x^1 + 1
- 0x0000100D, // x^13 + x^4 + x^3 + x^1 + 1
- 0x00002015, // x^14 + x^5 + x^3 + x^1 + 1
- 0x00004001, // x^15 + x^1 + 1
- 0x00008016, // x^16 + x^5 + x^3 + x^2 + 1
- 0x00010004, // x^17 + x^3 + 1
- 0x00020013, // x^18 + x^5 + x^2 + x^1 + 1
- 0x00040013, // x^19 + x^5 + x^2 + x^1 + 1
- 0x00080004, // x^20 + x^3 + 1
- 0x00100002, // x^21 + x^2 + 1
- 0x00200001, // x^22 + x^1 + 1
- 0x00400010, // x^23 + x^5 + 1
- 0x0080000D, // x^24 + x^4 + x^3 + x^1 + 1
- 0x01000004, // x^25 + x^3 + 1
- 0x02000023, // x^26 + x^6 + x^2 + x^1 + 1
- 0x04000013, // x^27 + x^5 + x^2 + x^1 + 1
- 0x08000004, // x^28 + x^3 + 1
- 0x10000002, // x^29 + x^2 + 1
- 0x20000029, // x^30 + x^4 + x^1 + 1
- 0x40000004, // x^31 + x^3 + 1
- 0x80000057 // x^32 + x^7 + x^5 + x^3 + x^2 + x^1 + 1
-};
-
-int gri_glfsr::glfsr_mask(int degree)
-{
- if (degree < 1 || degree > 32)
- throw std::runtime_error("gri_glfsr::glfsr_mask(): degree must be between 1 and 32 inclusive");
- return s_polynomial_masks[degree];
-}
diff --git a/gnuradio-core/src/lib/general/qa_general.cc b/gnuradio-core/src/lib/general/qa_general.cc
index 26b21983e6..61e5c159bd 100644
--- a/gnuradio-core/src/lib/general/qa_general.cc
+++ b/gnuradio-core/src/lib/general/qa_general.cc
@@ -33,7 +33,6 @@
#include <qa_gr_fxpt_nco.h>
#include <qa_gr_fxpt_vco.h>
#include <qa_gr_math.h>
-#include <qa_gri_lfsr.h>
CppUnit::TestSuite *
qa_general::suite ()
@@ -47,7 +46,6 @@ qa_general::suite ()
s->addTest (qa_gr_fxpt_nco::suite ());
s->addTest (qa_gr_fxpt_vco::suite ());
s->addTest (qa_gr_math::suite ());
- s->addTest (qa_gri_lfsr::suite ());
return s;
}
diff --git a/gnuradio-core/src/lib/general/qa_gri_lfsr.cc b/gnuradio-core/src/lib/general/qa_gri_lfsr.cc
deleted file mode 100644
index 87d610df68..0000000000
--- a/gnuradio-core/src/lib/general/qa_gri_lfsr.cc
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#include <gri_lfsr.h>
-#include <qa_gri_lfsr.h>
-#include <cppunit/TestAssert.h>
-#include <stdio.h>
-#include <string.h>
-#include <vector>
-
-void
-qa_gri_lfsr::test_lfsr ()
-{
- int mask = 0x19;
- int seed = 0x01;
- int length = 5;
-
- gri_lfsr lfsr1(mask,seed,length);
- gri_lfsr lfsr2(mask,seed,length);
-
- unsigned char expected[] = {1, 0, 1, 1, 0, 1, 0, 1, 0, 0};
-
- for(unsigned int i=0; i<31; i++){
- lfsr1.next_bit();
- }
-
- // test that after one lfsr cycle we still match out uncycled lfsr
- for (unsigned int i = 0; i < 41; i++) {
- CPPUNIT_ASSERT_EQUAL((int) lfsr1.next_bit(), (int) lfsr2.next_bit());
- }
-
- // test the known correct values at the given shift offset
- for(unsigned int i=0; i<10; i++){
- CPPUNIT_ASSERT_EQUAL((int) lfsr1.next_bit(), (int) expected[i]);
- }
-
- // test for register length too long
- CPPUNIT_ASSERT_THROW(gri_lfsr(mask, seed, 32), std::invalid_argument);
-}
-
-void
-qa_gri_lfsr::test_scrambler()
-{
- // CCSDS 7-bit scrambler
- int mask = 0x8A;
- int seed = 0x7F;
- int length = 7;
-
- gri_lfsr scrambler(mask, seed, length);
-
- // Impulse (1 and 126 more zeroes)
- unsigned char src[] =
- { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0 }; // flush bits
-
- // Impulse response (including leading bits)
- unsigned char expected[] =
- { 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0,
- 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1,
- 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1,
- 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0,
- 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0,
- 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0,
- 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0,
- 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, };
-
- int len = sizeof(src);
- std::vector<unsigned char> actual(len);
-
- for (int i = 0; i < len; i++)
- actual[i] = scrambler.next_bit_scramble(src[i]);
-
- CPPUNIT_ASSERT(memcmp(expected, &actual[0], len) == 0);
-}
-
-void
-qa_gri_lfsr::test_descrambler()
-{
- // CCSDS 7-bit scrambler
- int mask = 0x8A;
- int seed = 0x7F;
- int length = 7;
-
- gri_lfsr descrambler(mask, seed, length);
-
- // Scrambled sequence (impulse response)
- unsigned char src[] =
- { 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0,
- 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1,
- 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1,
- 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0,
- 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0,
- 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0,
- 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0,
- 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0 };
-
- // Original (garbage while synchronizing, them impulse)
- unsigned char expected[] =
- { 0, 1, 0, 0, 1, 0,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
- int len = sizeof(src);
- std::vector<unsigned char> actual(len);
-
- for (int i = 0; i < len; i++)
- actual[i] = descrambler.next_bit_descramble(src[i]);
-
- CPPUNIT_ASSERT(memcmp(expected, &actual[0], len) == 0);
-}
diff --git a/gnuradio-core/src/lib/gengen/CMakeLists.txt b/gnuradio-core/src/lib/gengen/CMakeLists.txt
index d137769907..ed49cf07e5 100644
--- a/gnuradio-core/src/lib/gengen/CMakeLists.txt
+++ b/gnuradio-core/src/lib/gengen/CMakeLists.txt
@@ -82,13 +82,14 @@ endmacro(expand_h_cc_i)
# Invoke macro to generate various sources
########################################################################
expand_h_cc_i(gr_vector_source_X b s i f c)
+expand_h_cc_i(gr_vector_insert_X b)
expand_h_cc_i(gr_vector_sink_X b s i f c)
expand_h_cc_i(gr_noise_source_X s i f c)
expand_h_cc_i(gr_sig_source_X s i f c)
expand_h_cc_i(gr_probe_signal_X b s i f c)
expand_h_cc_i(gr_probe_signal_vX b s i f c)
-expand_h_cc_i(gr_add_const_XX ss ii ff cc sf)
+expand_h_cc_i(gr_add_const_XX bb ss ii ff cc sf)
expand_h_cc_i(gr_multiply_const_XX ss ii)
expand_h_cc_i(gr_add_XX ss ii cc)
expand_h_cc_i(gr_sub_XX ss ii ff cc)
@@ -100,7 +101,6 @@ expand_h_cc_i(gr_multiply_const_vXX ss ii ff cc)
expand_h_cc_i(gr_integrate_XX ss ii ff cc)
expand_h_cc_i(gr_moving_average_XX ss ii ff cc)
-expand_h_cc_i(gr_chunks_to_symbols_XX bf bc sf sc if ic)
expand_h_cc_i(gr_unpacked_to_packed_XX bb ss ii)
expand_h_cc_i(gr_packed_to_unpacked_XX bb ss ii)
expand_h_cc_i(gr_xor_XX bb ss ii)
diff --git a/gnuradio-core/src/lib/gengen/generate_common.py b/gnuradio-core/src/lib/gengen/generate_common.py
index 13d01b0f90..37d8944f5b 100755
--- a/gnuradio-core/src/lib/gengen/generate_common.py
+++ b/gnuradio-core/src/lib/gengen/generate_common.py
@@ -54,7 +54,6 @@ reg_roots = [
# other blocks
others = (
- ('gr_chunks_to_symbols_XX', ('bf', 'bc', 'sf', 'sc', 'if', 'ic')),
('gr_unpacked_to_packed_XX', ('bb','ss','ii')),
('gr_packed_to_unpacked_XX', ('bb','ss','ii')),
('gr_xor_XX', ('bb','ss','ii')),
diff --git a/gnuradio-core/src/lib/gengen/gr_chunks_to_symbols_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_chunks_to_symbols_XX.cc.t
deleted file mode 100644
index 4a642c13e2..0000000000
--- a/gnuradio-core/src/lib/gengen/gr_chunks_to_symbols_XX.cc.t
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2010 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <@NAME@.h>
-#include <gr_io_signature.h>
-#include <assert.h>
-#include <iostream>
-#include <string.h>
-
-@SPTR_NAME@
-gr_make_@BASE_NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D)
-{
- return gnuradio::get_initial_sptr (new @NAME@ (symbol_table,D));
-}
-
-@NAME@::@NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D)
- : gr_sync_interpolator ("@BASE_NAME@",
- gr_make_io_signature (1, -1, sizeof (@I_TYPE@)),
- gr_make_io_signature (1, -1, sizeof (@O_TYPE@)),
- D),
- d_D (D),
- d_symbol_table (symbol_table)
-{
-}
-
-int
-@NAME@::work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- assert (noutput_items % d_D == 0);
- assert (input_items.size() == output_items.size());
- int nstreams = input_items.size();
-
- for (int m=0;m<nstreams;m++) {
- const @I_TYPE@ *in = (@I_TYPE@ *) input_items[m];
- @O_TYPE@ *out = (@O_TYPE@ *) output_items[m];
-
- // per stream processing
- for (int i = 0; i < noutput_items / d_D; i++){
- assert (((unsigned int)in[i]*d_D+d_D) <= d_symbol_table.size());
- memcpy(out, &d_symbol_table[(unsigned int)in[i]*d_D], d_D*sizeof(@O_TYPE@));
- out+=d_D;
- }
- // end of per stream processing
-
- }
- return noutput_items;
-}
diff --git a/gnuradio-core/src/lib/gengen/gr_chunks_to_symbols_XX.h.t b/gnuradio-core/src/lib/gengen/gr_chunks_to_symbols_XX.h.t
deleted file mode 100644
index 17d5688b86..0000000000
--- a/gnuradio-core/src/lib/gengen/gr_chunks_to_symbols_XX.h.t
+++ /dev/null
@@ -1,73 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gr_core_api.h>
-#include <gr_sync_interpolator.h>
-
-class @NAME@;
-typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
-
-GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D = 1);
-
-/*!
- * \brief Map a stream of symbol indexes (unpacked bytes or shorts) to stream of float or complex onstellation points.in \p D dimensions (\p D = 1 by default)
- * \ingroup converter_blk
- *
- * input: stream of @I_TYPE@; output: stream of @O_TYPE@
- *
- * out[n D + k] = symbol_table[in[n] D + k], k=0,1,...,D-1
- *
- * The combination of gr_packed_to_unpacked_XX followed by
- * gr_chunks_to_symbols_XY handles the general case of mapping
- * from a stream of bytes or shorts into arbitrary float
- * or complex symbols.
- *
- * \sa gr_packed_to_unpacked_bb, gr_unpacked_to_packed_bb,
- * \sa gr_packed_to_unpacked_ss, gr_unpacked_to_packed_ss,
- * \sa gr_chunks_to_symbols_bf, gr_chunks_to_symbols_bc.
- * \sa gr_chunks_to_symbols_sf, gr_chunks_to_symbols_sc.
- */
-
-class GR_CORE_API @NAME@ : public gr_sync_interpolator
-{
- friend GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D);
-
- int d_D;
- std::vector<@O_TYPE@> d_symbol_table;
- @NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D = 1);
-
- public:
- int D () const { return d_D; }
- std::vector<@O_TYPE@> symbol_table () const { return d_symbol_table; }
- int work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-
- bool check_topology(int ninputs, int noutputs) { return ninputs == noutputs; }
-};
-
-#endif
diff --git a/gnuradio-core/src/lib/gengen/gr_sig_source_X.cc.t b/gnuradio-core/src/lib/gengen/gr_sig_source_X.cc.t
index bdd0e810a7..6959eac824 100644
--- a/gnuradio-core/src/lib/gengen/gr_sig_source_X.cc.t
+++ b/gnuradio-core/src/lib/gengen/gr_sig_source_X.cc.t
@@ -29,6 +29,7 @@
#include <algorithm>
#include <gr_io_signature.h>
#include <stdexcept>
+#include <algorithm>
#include <gr_complex.h>
@@ -64,8 +65,7 @@ int
case GR_CONST_WAVE:
t = (gr_complex) d_ampl + d_offset;
- for (int i = 0; i < noutput_items; i++) // FIXME unroll
- optr[i] = t;
+ std::fill_n(optr, noutput_items, t);
break;
case GR_SIN_WAVE:
@@ -142,8 +142,7 @@ int
case GR_CONST_WAVE:
t = (@TYPE@) d_ampl + d_offset;
- for (int i = 0; i < noutput_items; i++) // FIXME unroll
- optr[i] = t;
+ std::fill_n(optr, noutput_items, t);
break;
case GR_SIN_WAVE:
diff --git a/gnuradio-core/src/lib/gengen/gr_vector_insert_X.cc.t b/gnuradio-core/src/lib/gengen/gr_vector_insert_X.cc.t
new file mode 100644
index 0000000000..37963cdfee
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_vector_insert_X.cc.t
@@ -0,0 +1,100 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <@NAME@.h>
+#include <algorithm>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+#include <stdio.h>
+
+@NAME@::@NAME@(const std::vector<@TYPE@> &data, int periodicity, int offset)
+ : gr_block("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof(@TYPE@)),
+ gr_make_io_signature (1, 1, sizeof(@TYPE@))),
+ d_data(data),
+ d_offset(offset),
+ d_periodicity(periodicity)
+{
+ //printf("INITIAL: periodicity = %d, offset = %d\n", periodicity, offset);
+ // some sanity checks
+ assert(offset < periodicity);
+ assert(offset >= 0);
+ assert(periodicity > data.size());
+}
+
+int
+@NAME@::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ @TYPE@ *out = (@TYPE@ *)output_items[0];
+ const @TYPE@ *in = (const @TYPE@ *)input_items[0];
+
+ int ii(0), oo(0);
+
+ while((oo < noutput_items) && (ii < ninput_items[0])) {
+
+ //printf("oo = %d, ii = %d, d_offset = %d, noutput_items = %d, ninput_items[0] = %d", oo, ii, d_offset, noutput_items, ninput_items[0]);
+ //printf(", d_periodicity = %d\n", d_periodicity);
+
+ if(d_offset >= ((int)d_data.size())) { // if we are in the copy region
+ int max_copy = std::min( std::min( noutput_items - oo, ninput_items[0] - ii ), d_periodicity - d_offset );
+ //printf("copy %d from input\n", max_copy);
+ memcpy( &out[oo], &in[ii], sizeof(@TYPE@)*max_copy );
+ //printf(" * memcpy returned.\n");
+ ii += max_copy;
+ oo += max_copy;
+ d_offset = (d_offset + max_copy)%d_periodicity;
+
+ }
+ else { // if we are in the insertion region
+ int max_copy = std::min( noutput_items - oo, ((int)d_data.size()) - d_offset );
+ //printf("copy %d from d_data[%d] to out[%d]\n", max_copy, d_offset, oo);
+ memcpy( &out[oo], &d_data[d_offset], sizeof(@TYPE@)*max_copy );
+ //printf(" * memcpy returned.\n");
+ oo += max_copy;
+ d_offset = (d_offset + max_copy)%d_periodicity;
+ //printf(" ## (inelse) oo = %d, d_offset = %d\n", oo, d_offset);
+ }
+
+ //printf(" # exit else, on to next loop.\n");
+ }
+ //printf(" # got out of loop\n");
+
+ //printf("consume = %d, produce = %d\n", ii, oo);
+ consume_each(ii);
+ return oo;
+}
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (const std::vector<@TYPE@> &data, int periodicity, int offset)
+{
+ return gnuradio::get_initial_sptr(new @NAME@ (data, periodicity, offset));
+}
+
diff --git a/gnuradio-core/src/lib/gengen/gr_vector_insert_X.h.t b/gnuradio-core/src/lib/gengen/gr_vector_insert_X.h.t
new file mode 100644
index 0000000000..26f851700d
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_vector_insert_X.h.t
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+
+class GR_CORE_API @NAME@;
+typedef boost::shared_ptr<@NAME@> @NAME@_sptr;
+
+/*!
+ * \brief source of @TYPE@'s that gets its data from a vector
+ * \ingroup source_blk
+ */
+
+class @NAME@ : public gr_block {
+ friend GR_CORE_API @NAME@_sptr
+ gr_make_@BASE_NAME@(const std::vector<@TYPE@> &data, int periodicity, int offset);
+
+ std::vector<@TYPE@> d_data;
+ int d_offset;
+ int d_periodicity;
+
+ @NAME@(const std::vector<@TYPE@> &data, int periodicity, int offset);
+
+ public:
+ void rewind() {d_offset=0;}
+ virtual int general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ void set_data(const std::vector<@TYPE@> &data){ d_data = data; rewind(); }
+};
+
+GR_CORE_API @NAME@_sptr
+gr_make_@BASE_NAME@(const std::vector<@TYPE@> &data, int periodicity, int offset=0);
+
+#endif
diff --git a/gnuradio-core/src/lib/gengen/gr_chunks_to_symbols_XX.i.t b/gnuradio-core/src/lib/gengen/gr_vector_insert_X.i.t
index 14c8be4863..f3341eec4f 100644
--- a/gnuradio-core/src/lib/gengen/gr_chunks_to_symbols_XX.i.t
+++ b/gnuradio-core/src/lib/gengen/gr_vector_insert_X.i.t
@@ -1,19 +1,19 @@
/* -*- c++ -*- */
/*
- * Copyright 2004 Free Software Foundation, Inc.
- *
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
* This file is part of GNU Radio
- *
+ *
* GNU Radio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
- *
+ *
* GNU Radio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Radio; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
@@ -24,14 +24,14 @@
GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
-@SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D = 1);
+@NAME@_sptr
+gr_make_@BASE_NAME@ (const std::vector<@TYPE@> &data, int periodicity, int offset = 0)
+ throw(std::invalid_argument);
-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; }
+class @NAME@ : public gr_block {
+ public:
+ void rewind();
+ void set_data(const std::vector<@TYPE@> &data);
+ private:
+ @NAME@ (const std::vector<@TYPE@> &data, int periodicity, int offset = 0);
};
diff --git a/gnuradio-core/src/lib/gengen/gr_vector_source_X.h.t b/gnuradio-core/src/lib/gengen/gr_vector_source_X.h.t
index fe0a77f818..fe02c1346f 100644
--- a/gnuradio-core/src/lib/gengen/gr_vector_source_X.h.t
+++ b/gnuradio-core/src/lib/gengen/gr_vector_source_X.h.t
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004,2008 Free Software Foundation, Inc.
+ * Copyright 2004,2008,2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -52,6 +52,7 @@ class @NAME@ : public gr_sync_block {
virtual int work (int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
+ void set_data(const std::vector<@TYPE@> &data){ d_data = data; rewind(); }
};
GR_CORE_API @NAME@_sptr
diff --git a/gnuradio-core/src/lib/gengen/gr_vector_source_X.i.t b/gnuradio-core/src/lib/gengen/gr_vector_source_X.i.t
index 6c20539ac8..4986c68a35 100644
--- a/gnuradio-core/src/lib/gengen/gr_vector_source_X.i.t
+++ b/gnuradio-core/src/lib/gengen/gr_vector_source_X.i.t
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004,2008 Free Software Foundation, Inc.
+ * Copyright 2004,2008,2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -30,7 +30,8 @@ gr_make_@BASE_NAME@ (const std::vector<@TYPE@> &data, bool repeat = false, int v
class @NAME@ : public gr_sync_block {
public:
- void rewind() {d_offset=0;}
+ void rewind();
+ void set_data(const std::vector<@TYPE@> &data);
private:
@NAME@ (const std::vector<@TYPE@> &data, int vlen);
};
diff --git a/gnuradio-core/src/lib/io/gri_wavfile.cc b/gnuradio-core/src/lib/io/gri_wavfile.cc
index e316a08254..780bd1b98f 100644
--- a/gnuradio-core/src/lib/io/gri_wavfile.cc
+++ b/gnuradio-core/src/lib/io/gri_wavfile.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004,2008 Free Software Foundation, Inc.
+ * Copyright 2004,2008,2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -27,107 +27,30 @@
#include <gri_wavfile.h>
#include <cstring>
#include <stdint.h>
+#include <boost/asio.hpp>
# define VALID_COMPRESSION_TYPE 0x0001
// WAV files are always little-endian, so we need some byte switching macros
-// FIXME: Use libgruel versions
-
+// Basically, this is the opposite of htonx() and ntohx()
#ifdef WORDS_BIGENDIAN
-#ifdef HAVE_BYTESWAP_H
-#include <byteswap.h>
-#else
-#warning Using non-portable code (likely wrong other than ILP32).
-
-static inline short int
-bswap_16 (unsigned short int x)
-{
- return ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8));
-}
-
-static inline unsigned int
-bswap_32 (unsigned int x)
-{
- return ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) \
- | (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24));
-}
-#endif // HAVE_BYTESWAP_H
-
-static inline uint32_t
-host_to_wav(uint32_t x)
-{
- return bswap_32(x);
-}
-
-static inline uint16_t
-host_to_wav(uint16_t x)
-{
- return bswap_16(x);
-}
-
-static inline int16_t
-host_to_wav(int16_t x)
-{
- return bswap_16(x);
-}
-
-static inline uint32_t
-wav_to_host(uint32_t x)
-{
- return bswap_32(x);
-}
-
-static inline uint16_t
-wav_to_host(uint16_t x)
-{
- return bswap_16(x);
-}
-
-static inline int16_t
-wav_to_host(int16_t x)
-{
- return bswap_16(x);
-}
+static inline uint32_t host_to_wav(uint32_t x) { return htonl(x); }
+static inline uint16_t host_to_wav(uint16_t x) { return htons(x); }
+static inline int16_t host_to_wav(int16_t x) { return htons(x); }
+static inline uint32_t wav_to_host(uint32_t x) { return ntohl(x); }
+static inline uint16_t wav_to_host(uint16_t x) { return ntohs(x); }
+static inline int16_t wav_to_host(int16_t x) { return ntohs(x); }
#else
-static inline uint32_t
-host_to_wav(uint32_t x)
-{
- return x;
-}
-
-static inline uint16_t
-host_to_wav(uint16_t x)
-{
- return x;
-}
-
-static inline int16_t
-host_to_wav(int16_t x)
-{
- return x;
-}
-
-static inline uint32_t
-wav_to_host(uint32_t x)
-{
- return x;
-}
-
-static inline uint16_t
-wav_to_host(uint16_t x)
-{
- return x;
-}
-
-static inline int16_t
-wav_to_host(int16_t x)
-{
- return x;
-}
+static inline uint32_t host_to_wav(uint32_t x) { return x; }
+static inline uint16_t host_to_wav(uint16_t x) { return x; }
+static inline int16_t host_to_wav(int16_t x) { return x; }
+static inline uint32_t wav_to_host(uint32_t x) { return x; }
+static inline uint16_t wav_to_host(uint16_t x) { return x; }
+static inline int16_t wav_to_host(int16_t x) { return x; }
#endif // WORDS_BIGENDIAN
@@ -225,12 +148,15 @@ gri_wavheader_parse(FILE *fp,
short int
gri_wav_read_sample(FILE *fp, int bytes_per_sample)
{
- int16_t buf = 0;
- size_t fresult;
-
- fresult = fread(&buf, bytes_per_sample, 1, fp);
+ int16_t buf_16bit;
- return (short) wav_to_host(buf);
+ if(!fread(&buf_16bit, bytes_per_sample, 1, fp)) {
+ return 0;
+ }
+ if(bytes_per_sample == 1) {
+ return (short) buf_16bit;
+ }
+ return (short)wav_to_host(buf_16bit);
}
diff --git a/gnuradio-core/src/lib/io/gri_wavfile.h b/gnuradio-core/src/lib/io/gri_wavfile.h
index c757be26bc..16280e34a9 100644
--- a/gnuradio-core/src/lib/io/gri_wavfile.h
+++ b/gnuradio-core/src/lib/io/gri_wavfile.h
@@ -29,20 +29,15 @@
/*!
* \brief Read signal information from a given WAV file.
*
- * \p fp File pointer to an opened, empty file.
- * \p sample_rate Stores the sample rate [S/s]
- * \p nchans Number of channels
- * \p bytes_per_sample Bytes per sample, can either be 1 or 2 (corresponding to
- * 8 or 16 bit samples, respectively)
- * \p first_sample_pos Number of the first byte containing a sample. Use this
- * with fseek() to jump from the end of the file to the first sample
- * when in repeat mode.
- * \p samples_per_chan Number of samples per channel
- * \p normalize_fac The normalization factor with which you need to divide the
- * integer values of the samples to get them within [-1;1]
- * \p normalize_shift The value by which the sample values need to be shifted
- * after normalization (reason being, 8-bit WAV files store samples as
- * unsigned char and 16-bit as signed short int)
+ * \param[in] fp File pointer to an opened, empty file.
+ * \param[out] sample_rate Stores the sample rate [S/s]
+ * \param[out] nchans Number of channels
+ * \param[out] bytes_per_sample Bytes per sample, can either be 1 or 2 (corresponding o
+ * 8 or 16 bit samples, respectively)
+ * \param[out] first_sample_pos Number of the first byte containing a sample. Use this
+ * with fseek() to jump from the end of the file to the
+ * first sample when in repeat mode.
+ * \param[out] samples_per_chan Number of samples per channel
* \return True on a successful read, false if the file could not be read or is
* not a valid WAV file.
*/
@@ -94,8 +89,8 @@ gri_wav_write_sample(FILE *fp, short int sample, int bytes_per_sample);
* shouldn't happen), you need to fseek() to the end of the file (or
* whereever).
*
- * \p fp File pointer to an open WAV file with a blank header
- * \p byte_count Length of all samples written to the file in bytes.
+ * \param[in] fp File pointer to an open WAV file with a blank header
+ * \param[in] byte_count Length of all samples written to the file in bytes.
*/
bool
gri_wavheader_complete(FILE *fp, unsigned int byte_count);
diff --git a/gnuradio-core/src/lib/runtime/gr_top_block.i b/gnuradio-core/src/lib/runtime/gr_top_block.i
index 80a1b82aea..6ae4c65a99 100644
--- a/gnuradio-core/src/lib/runtime/gr_top_block.i
+++ b/gnuradio-core/src/lib/runtime/gr_top_block.i
@@ -20,8 +20,6 @@
* Boston, MA 02110-1301, USA.
*/
-%include <gr_top_block.i>
-
class gr_top_block;
typedef boost::shared_ptr<gr_top_block> gr_top_block_sptr;
%template(gr_top_block_sptr) boost::shared_ptr<gr_top_block>;
diff --git a/gnuradio-core/src/python/build_utils.py b/gnuradio-core/src/python/build_utils.py
index ce07579123..77bf0607a3 100644
--- a/gnuradio-core/src/python/build_utils.py
+++ b/gnuradio-core/src/python/build_utils.py
@@ -182,7 +182,7 @@ def standard_dict (name, code3, package='gr'):
d['GUARD_NAME'] = 'INCLUDED_%s_H' % name.upper ()
d['BASE_NAME'] = re.sub ('^' + package + '_', '', name)
d['SPTR_NAME'] = '%s_sptr' % name
- d['WARNING'] = 'WARNING: this file is machine generated. Edits will be over written'
+ d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten'
d['COPYRIGHT'] = copyright
d['TYPE'] = i_type (code3)
d['I_TYPE'] = i_type (code3)
@@ -190,3 +190,35 @@ def standard_dict (name, code3, package='gr'):
d['TAP_TYPE'] = tap_type (code3)
d['IS_COMPLEX'] = is_complex (code3)
return d
+
+
+def standard_dict2 (name, code3, package):
+ d = {}
+ d['NAME'] = name
+ d['BASE_NAME'] = name
+ d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper())
+ d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten'
+ d['COPYRIGHT'] = copyright
+ d['TYPE'] = i_type (code3)
+ d['I_TYPE'] = i_type (code3)
+ d['O_TYPE'] = o_type (code3)
+ d['TAP_TYPE'] = tap_type (code3)
+ d['IS_COMPLEX'] = is_complex (code3)
+ return d
+
+def standard_impl_dict2 (name, code3, package):
+ d = {}
+ d['NAME'] = name
+ d['IMPL_NAME'] = name
+ d['BASE_NAME'] = name.rstrip("_impl")
+ d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper())
+ d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten'
+ d['COPYRIGHT'] = copyright
+ d['FIR_TYPE'] = "fir_filter_" + code3
+ d['CFIR_TYPE'] = "fir_filter_" + code3[0:2] + 'c'
+ d['TYPE'] = i_type (code3)
+ d['I_TYPE'] = i_type (code3)
+ d['O_TYPE'] = o_type (code3)
+ d['TAP_TYPE'] = tap_type (code3)
+ d['IS_COMPLEX'] = is_complex (code3)
+ return d
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_diff_encoder.py b/gnuradio-core/src/python/gnuradio/gr/qa_diff_encoder.py
deleted file mode 100755
index c1fe2a7000..0000000000
--- a/gnuradio-core/src/python/gnuradio/gr/qa_diff_encoder.py
+++ /dev/null
@@ -1,86 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2006,2007,2010 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GNU Radio is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr, gr_unittest
-import math
-import random
-
-def make_random_int_tuple(L, min, max):
- result = []
- for x in range(L):
- result.append(random.randint(min, max))
- return tuple(result)
-
-
-class test_diff_encoder (gr_unittest.TestCase):
-
- def setUp (self):
- self.tb = gr.top_block ()
-
- def tearDown (self):
- self.tb = None
-
- def test_diff_encdec_000(self):
- random.seed(0)
- modulus = 2
- src_data = make_random_int_tuple(1000, 0, modulus-1)
- expected_result = src_data
- src = gr.vector_source_b(src_data)
- enc = gr.diff_encoder_bb(modulus)
- dec = gr.diff_decoder_bb(modulus)
- dst = gr.vector_sink_b()
- self.tb.connect(src, enc, dec, dst)
- self.tb.run() # run the graph and wait for it to finish
- actual_result = dst.data() # fetch the contents of the sink
- self.assertEqual(expected_result, actual_result)
-
- def test_diff_encdec_001(self):
- random.seed(0)
- modulus = 4
- src_data = make_random_int_tuple(1000, 0, modulus-1)
- expected_result = src_data
- src = gr.vector_source_b(src_data)
- enc = gr.diff_encoder_bb(modulus)
- dec = gr.diff_decoder_bb(modulus)
- dst = gr.vector_sink_b()
- self.tb.connect(src, enc, dec, dst)
- self.tb.run() # run the graph and wait for it to finish
- actual_result = dst.data() # fetch the contents of the sink
- self.assertEqual(expected_result, actual_result)
-
- def test_diff_encdec_002(self):
- random.seed(0)
- modulus = 8
- src_data = make_random_int_tuple(40000, 0, modulus-1)
- expected_result = src_data
- src = gr.vector_source_b(src_data)
- enc = gr.diff_encoder_bb(modulus)
- dec = gr.diff_decoder_bb(modulus)
- dst = gr.vector_sink_b()
- self.tb.connect(src, enc, dec, dst)
- self.tb.run() # run the graph and wait for it to finish
- actual_result = dst.data() # fetch the contents of the sink
- self.assertEqual(expected_result, actual_result)
-
-if __name__ == '__main__':
- gr_unittest.run(test_diff_encoder, "test_diff_encoder.xml")
-
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_fsk_stuff.py b/gnuradio-core/src/python/gnuradio/gr/qa_fsk_stuff.py
deleted file mode 100755
index 95b8c06641..0000000000
--- a/gnuradio-core/src/python/gnuradio/gr/qa_fsk_stuff.py
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2004,2007,2010 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GNU Radio is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr, gr_unittest
-import math
-
-def sincos(x):
- return math.cos(x) + math.sin(x) * 1j
-
-class test_bytes_to_syms (gr_unittest.TestCase):
-
- def setUp (self):
- self.tb = gr.top_block ()
-
- def tearDown (self):
- self.tb = None
-
- def test_bytes_to_syms_001 (self):
- src_data = (0x01, 0x80, 0x03)
- expected_result = (-1, -1, -1, -1, -1, -1, -1, +1,
- +1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, +1, +1)
- src = gr.vector_source_b (src_data)
- op = gr.bytes_to_syms ()
- dst = gr.vector_sink_f ()
- self.tb.connect (src, op)
- self.tb.connect (op, dst)
- self.tb.run ()
- result_data = dst.data ()
- self.assertEqual (expected_result, result_data)
-
- def test_simple_framer (self):
- src_data = (0x00, 0x11, 0x22, 0x33,
- 0x44, 0x55, 0x66, 0x77,
- 0x88, 0x99, 0xaa, 0xbb,
- 0xcc, 0xdd, 0xee, 0xff)
-
- expected_result = (
- 0xac, 0xdd, 0xa4, 0xe2, 0xf2, 0x8c, 0x20, 0xfc, 0x00, 0x00, 0x11, 0x22, 0x33, 0x55,
- 0xac, 0xdd, 0xa4, 0xe2, 0xf2, 0x8c, 0x20, 0xfc, 0x01, 0x44, 0x55, 0x66, 0x77, 0x55,
- 0xac, 0xdd, 0xa4, 0xe2, 0xf2, 0x8c, 0x20, 0xfc, 0x02, 0x88, 0x99, 0xaa, 0xbb, 0x55,
- 0xac, 0xdd, 0xa4, 0xe2, 0xf2, 0x8c, 0x20, 0xfc, 0x03, 0xcc, 0xdd, 0xee, 0xff, 0x55)
-
- src = gr.vector_source_b (src_data)
- op = gr.simple_framer (4)
- dst = gr.vector_sink_b ()
- self.tb.connect (src, op)
- self.tb.connect (op, dst)
- self.tb.run ()
- result_data = dst.data ()
- self.assertEqual (expected_result, result_data)
-
-
-if __name__ == '__main__':
- gr_unittest.run(test_bytes_to_syms, "test_bytes_to_syms.xml")
-
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_glfsr_source.py b/gnuradio-core/src/python/gnuradio/gr/qa_glfsr_source.py
deleted file mode 100755
index 161e4a5cc1..0000000000
--- a/gnuradio-core/src/python/gnuradio/gr/qa_glfsr_source.py
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2007,2010 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GNU Radio is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr, gr_unittest
-
-class test_glfsr_source(gr_unittest.TestCase):
-
- def setUp (self):
- self.tb = gr.top_block ()
-
- def tearDown (self):
- self.tb = None
-
- def test_000_make_b(self):
- src = gr.glfsr_source_b(16)
- self.assertEquals(src.mask(), 0x8016)
- self.assertEquals(src.period(), 2**16-1)
-
- def test_001_degree_b(self):
- self.assertRaises(RuntimeError,
- lambda: gr.glfsr_source_b(0))
- self.assertRaises(RuntimeError,
- lambda: gr.glfsr_source_b(33))
-
- def test_002_correlation_b(self):
- for degree in range(1,11): # Higher degrees take too long to correlate
- src = gr.glfsr_source_b(degree, False)
- b2f = gr.chunks_to_symbols_bf((-1.0,1.0), 1)
- dst = gr.vector_sink_f()
- del self.tb # Discard existing top block
- self.tb = gr.top_block()
- self.tb.connect(src, b2f, dst)
- self.tb.run()
- self.tb.disconnect_all()
- actual_result = dst.data()
- R = auto_correlate(actual_result)
- self.assertEqual(R[0], float(len(R))) # Auto-correlation peak at origin
- for i in range(len(R)-1):
- self.assertEqual(R[i+1], -1.0) # Auto-correlation minimum everywhere else
-
- def test_003_make_f(self):
- src = gr.glfsr_source_f(16)
- self.assertEquals(src.mask(), 0x8016)
- self.assertEquals(src.period(), 2**16-1)
-
- def test_004_degree_f(self):
- self.assertRaises(RuntimeError,
- lambda: gr.glfsr_source_f(0))
- self.assertRaises(RuntimeError,
- lambda: gr.glfsr_source_f(33))
- def test_005_correlation_f(self):
- for degree in range(1,11): # Higher degrees take too long to correlate
- src = gr.glfsr_source_f(degree, False)
- dst = gr.vector_sink_f()
- del self.tb # Discard existing top block
- self.tb = gr.top_block()
- self.tb.connect(src, dst)
- self.tb.run()
-
- actual_result = dst.data()
- R = auto_correlate(actual_result)
- self.assertEqual(R[0], float(len(R))) # Auto-correlation peak at origin
- for i in range(len(R)-1):
- self.assertEqual(R[i+1], -1.0) # Auto-correlation minimum everywhere else
-
-def auto_correlate(data):
- l = len(data)
- R = [0,]*l
- for lag in range(l):
- for i in range(l):
- R[lag] += data[i]*data[i-lag]
- return R
-
-if __name__ == '__main__':
- gr_unittest.run(test_glfsr_source, "test_glfsr_source.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_keep_m_in_n.py b/gnuradio-core/src/python/gnuradio/gr/qa_keep_m_in_n.py
new file mode 100755
index 0000000000..922671d024
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_keep_m_in_n.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+#
+# Copyright 2008,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+from gnuradio import gr, gr_unittest
+import sys
+import random
+
+class test_keep_m_in_n(gr_unittest.TestCase):
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_001(self):
+ self.maxDiff = None;
+ tb = gr.top_block()
+ src = gr.vector_source_b( range(0,100) )
+
+ # itemsize, M, N, offset
+ km2 = gr.keep_m_in_n( 1, 1, 2, 0 );
+ km3 = gr.keep_m_in_n( 1, 1, 3, 1 );
+ km7 = gr.keep_m_in_n( 1, 1, 7, 2 );
+ snk2 = gr.vector_sink_b();
+ snk3 = gr.vector_sink_b();
+ snk7 = gr.vector_sink_b();
+ tb.connect(src,km2,snk2);
+ tb.connect(src,km3,snk3);
+ tb.connect(src,km7,snk7);
+ tb.run();
+
+ self.assertEqual(range(0,100,2), list(snk2.data()));
+ self.assertEqual(range(1,100,3), list(snk3.data()));
+ self.assertEqual(range(2,100,7), list(snk7.data()));
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_keep_m_in_n, "test_keep_m_in_n.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_pack_k_bits.py b/gnuradio-core/src/python/gnuradio/gr/qa_pack_k_bits.py
new file mode 100755
index 0000000000..25fc5e9fcc
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_pack_k_bits.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python
+#
+# Copyright 2006,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import random
+
+class test_pack(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block ()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_001(self):
+ src_data = (1,0,1,1,0,1,1,0)
+ expected_results = (1,0,1,1,0,1,1,0)
+ src = gr.vector_source_b(src_data,False)
+ op = gr.pack_k_bits_bb(1)
+ dst = gr.vector_sink_b()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ self.assertEqual(expected_results, dst.data())
+
+ def test_002(self):
+ src_data = (1,0,1,1,0,0,0,1)
+ expected_results = ( 2, 3, 0, 1)
+ src = gr.vector_source_b(src_data,False)
+ op = gr.pack_k_bits_bb(2)
+ dst = gr.vector_sink_b()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ #self.assertEqual(expected_results, dst.data())
+ self.assertEqual(expected_results, dst.data())
+
+ def test_003(self):
+ src_data = expected_results = map(lambda x: random.randint(0,3), range(10));
+ src = gr.vector_source_b( src_data );
+ pack = gr.pack_k_bits_bb(2);
+ unpack = gr.unpack_k_bits_bb(2);
+ snk = gr.vector_sink_b();
+ self.tb.connect(src,unpack,pack,snk);
+ self.tb.run()
+ self.assertEqual(list(expected_results), list(snk.data()));
+
+if __name__ == '__main__':
+ gr_unittest.run(test_pack, "test_pack.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_scrambler.py b/gnuradio-core/src/python/gnuradio/gr/qa_scrambler.py
deleted file mode 100755
index 5fe89bdc7f..0000000000
--- a/gnuradio-core/src/python/gnuradio/gr/qa_scrambler.py
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2008,2010 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GNU Radio is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr, gr_unittest
-
-class test_scrambler(gr_unittest.TestCase):
-
- def setUp (self):
- self.tb = gr.top_block()
-
- def tearDown(self):
- self.tb = None
-
- def test_scrambler_descrambler(self):
- src_data = (1,)*1000
- src = gr.vector_source_b(src_data, False)
- scrambler = gr.scrambler_bb(0x8a, 0x7F, 7) # CCSDS 7-bit scrambler
- descrambler = gr.descrambler_bb(0x8a, 0x7F, 7)
- dst = gr.vector_sink_b()
- self.tb.connect(src, scrambler, descrambler, dst)
- self.tb.run()
- self.assertEqual(tuple(src_data[:-8]), dst.data()[8:]) # skip garbage during synchronization
-
- def test_additive_scrambler(self):
- src_data = (1,)*1000
- src = gr.vector_source_b(src_data, False)
- scrambler = gr.additive_scrambler_bb(0x8a, 0x7f, 7)
- descrambler = gr.additive_scrambler_bb(0x8a, 0x7f, 7)
- dst = gr.vector_sink_b()
- self.tb.connect(src, scrambler, descrambler, dst)
- self.tb.run()
- self.assertEqual(src_data, dst.data())
-
- def test_additive_scrambler_reset(self):
- src_data = (1,)*1000
- src = gr.vector_source_b(src_data, False)
- scrambler = gr.additive_scrambler_bb(0x8a, 0x7f, 7, 100)
- descrambler = gr.additive_scrambler_bb(0x8a, 0x7f, 7, 100)
- dst = gr.vector_sink_b()
- self.tb.connect(src, scrambler, descrambler, dst)
- self.tb.run()
- self.assertEqual(src_data, dst.data())
-
-if __name__ == '__main__':
- gr_unittest.run(test_scrambler, "test_scrambler.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_pn_correlator_cc.py b/gnuradio-core/src/python/gnuradio/gr/qa_tag_debug.py
index 6a62a6997b..81babca048 100755
--- a/gnuradio-core/src/python/gnuradio/gr/qa_pn_correlator_cc.py
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_tag_debug.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2007,2010 Free Software Foundation, Inc.
+# Copyright 2012 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -22,29 +22,22 @@
from gnuradio import gr, gr_unittest
-class test_pn_correlator_cc(gr_unittest.TestCase):
+class test_tag_debug(gr_unittest.TestCase):
def setUp(self):
- self.tb = gr.top_block ()
+ self.tb = gr.top_block()
def tearDown(self):
self.tb = None
- def test_000_make(self):
- c = gr.pn_correlator_cc(10)
-
- def test_001_correlate(self):
- degree = 10
- length = 2**degree-1
- src = gr.glfsr_source_f(degree)
- head = gr.head(gr.sizeof_float, length*length)
- f2c = gr.float_to_complex()
- corr = gr.pn_correlator_cc(degree)
- dst = gr.vector_sink_c()
- self.tb.connect(src, head, f2c, corr, dst)
+ def test_001(self):
+ # Just run some data through and make sure it doesn't puke.
+ src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+ src = gr.vector_source_i(src_data)
+ op = gr.tag_debug(gr.sizeof_int, "tag QA")
+ self.tb.connect(src, op)
self.tb.run()
- data = dst.data()
- self.assertEqual(data[-1], (1.0+0j))
+ x = op.current_tags()
if __name__ == '__main__':
- gr_unittest.run(test_pn_correlator_cc, "test_pn_correlator_cc.xml")
+ gr_unittest.run(test_tag_debug, "test_tag_debug.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_diff_phasor_cc.py b/gnuradio-core/src/python/gnuradio/gr/qa_vector_insert.py
index 41f96aa616..acc06dfded 100755
--- a/gnuradio-core/src/python/gnuradio/gr/qa_diff_phasor_cc.py
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_vector_insert.py
@@ -1,29 +1,29 @@
#!/usr/bin/env python
#
-# Copyright 2004,2007,2010 Free Software Foundation, Inc.
-#
+# Copyright 2012 Free Software Foundation, Inc.
+#
# This file is part of GNU Radio
-#
+#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
-#
+#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
-#
+#
from gnuradio import gr, gr_unittest
import math
-class test_diff_phasor (gr_unittest.TestCase):
+class test_vector_insert(gr_unittest.TestCase):
def setUp (self):
self.tb = gr.top_block ()
@@ -31,20 +31,28 @@ class test_diff_phasor (gr_unittest.TestCase):
def tearDown (self):
self.tb = None
- def test_diff_phasor_cc (self):
- src_data = (0+0j, 1+0j, -1+0j, 3+4j, -3-4j, -3+4j)
- expected_result = (0+0j, 0+0j, -1+0j, -3-4j, -25+0j, -7-24j)
- src = gr.vector_source_c (src_data)
- op = gr.diff_phasor_cc ()
- dst = gr.vector_sink_c ()
- self.tb.connect (src, op)
- self.tb.connect (op, dst)
- self.tb.run () # run the graph and wait for it to finish
- actual_result = dst.data () # fetch the contents of the sink
- self.assertComplexTuplesAlmostEqual (expected_result, actual_result)
+ def test_001(self):
+ src_data = [float(x) for x in range(16)]
+ expected_result = tuple(src_data)
+
+ period = 9177;
+ offset = 0;
+
+ src = gr.null_source(1)
+ head = gr.head(1, 10000000);
+ ins = gr.vector_insert_b([1], period, offset);
+ dst = gr.vector_sink_b()
+ self.tb.connect(src, head, ins, dst)
+ self.tb.run()
+ result_data = dst.data()
+ for i in range(10000):
+ if(i%period == offset):
+ self.assertEqual(1, result_data[i])
+ else:
+ self.assertEqual(0, result_data[i])
if __name__ == '__main__':
- gr_unittest.run(test_diff_phasor, "test_diff_phasor.xml")
+ gr_unittest.run(test_vector_insert, "test_vector_insert.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_vector_map.py b/gnuradio-core/src/python/gnuradio/gr/qa_vector_map.py
new file mode 100644
index 0000000000..12f4be5898
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_vector_map.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_vector_map(gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_reversing(self):
+ # Chunk data in blocks of N and reverse the block contents.
+ N = 5
+ src_data = range(0, 20)
+ expected_result = []
+ for i in range(N-1, len(src_data), N):
+ for j in range(0, N):
+ expected_result.append(1.0*(i-j))
+ mapping = [list(reversed([(0, i) for i in range(0, N)]))]
+ src = gr.vector_source_f(src_data, False, N)
+ vmap = gr.vector_map(gr.sizeof_float, (N, ), mapping)
+ dst = gr.vector_sink_f(N)
+ self.tb.connect(src, vmap, dst)
+ self.tb.run()
+ result_data = list(dst.data())
+ self.assertEqual(expected_result, result_data)
+
+ def test_vector_to_streams(self):
+ # Split an input vector into N streams.
+ N = 5
+ M = 20
+ src_data = range(0, M)
+ expected_results = []
+ for n in range(0, N):
+ expected_results.append(range(n, M, N))
+ mapping = [[(0, n)] for n in range(0, N)]
+ src = gr.vector_source_f(src_data, False, N)
+ vmap = gr.vector_map(gr.sizeof_float, (N, ), mapping)
+ dsts = [gr.vector_sink_f(1) for n in range(0, N)]
+ self.tb.connect(src, vmap)
+ for n in range(0, N):
+ self.tb.connect((vmap, n), dsts[n])
+ self.tb.run()
+ for n in range(0, N):
+ result_data = list(dsts[n].data())
+ self.assertEqual(expected_results[n], result_data)
+
+ def test_interleaving(self):
+ # Takes 3 streams (a, b and c)
+ # Outputs 2 streams.
+ # First (d) is interleaving of a and b.
+ # Second (e) is interleaving of a and b and c. c is taken in
+ # chunks of 2 which are reversed.
+ A = (1, 2, 3, 4, 5)
+ B = (11, 12, 13, 14, 15)
+ C = (99, 98, 97, 96, 95, 94, 93, 92, 91, 90)
+ expected_D = (1, 11, 2, 12, 3, 13, 4, 14, 5, 15)
+ expected_E = (1, 11, 98, 99, 2, 12, 96, 97, 3, 13, 94, 95,
+ 4, 14, 92, 93, 5, 15, 90, 91)
+ mapping = [[(0, 0), (1, 0)], # mapping to produce D
+ [(0, 0), (1, 0), (2, 1), (2, 0)], # mapping to produce E
+ ]
+ srcA = gr.vector_source_f(A, False, 1)
+ srcB = gr.vector_source_f(B, False, 1)
+ srcC = gr.vector_source_f(C, False, 2)
+ vmap = gr.vector_map(gr.sizeof_int, (1, 1, 2), mapping)
+ dstD = gr.vector_sink_f(2)
+ dstE = gr.vector_sink_f(4)
+ self.tb.connect(srcA, (vmap, 0))
+ self.tb.connect(srcB, (vmap, 1))
+ self.tb.connect(srcC, (vmap, 2))
+ self.tb.connect((vmap, 0), dstD)
+ self.tb.connect((vmap, 1), dstE)
+ self.tb.run()
+ self.assertEqual(expected_D, dstD.data())
+ self.assertEqual(expected_E, dstE.data())
+
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_vector_map, "test_vector_map.xml")
+
diff --git a/gr-audio/examples/python/noise.py b/gr-audio/examples/python/noise.py
index 12eee1906d..bba9e83eae 100755
--- a/gr-audio/examples/python/noise.py
+++ b/gr-audio/examples/python/noise.py
@@ -22,6 +22,7 @@
from gnuradio import gr
from gnuradio import audio
+from gnuradio import digital
from gnuradio.eng_option import eng_option
from optparse import OptionParser
@@ -44,7 +45,7 @@ class my_top_block(gr.top_block):
ampl = 0.1
src = gr.glfsr_source_b(32) # Pseudorandom noise source
- b2f = gr.chunks_to_symbols_bf([ampl, -ampl], 1)
+ b2f = digital.chunks_to_symbols_bf([ampl, -ampl], 1)
dst = audio.sink(sample_rate, options.audio_output)
self.connect(src, b2f, dst)
diff --git a/gr-audio/lib/CMakeLists.txt b/gr-audio/lib/CMakeLists.txt
index 7e0252a8b1..c1781af79e 100644
--- a/gr-audio/lib/CMakeLists.txt
+++ b/gr-audio/lib/CMakeLists.txt
@@ -150,4 +150,4 @@ add_library(gnuradio-audio SHARED ${gr_audio_sources})
target_link_libraries(gnuradio-audio ${gr_audio_libs})
GR_LIBRARY_FOO(gnuradio-audio RUNTIME_COMPONENT "audio_runtime" DEVEL_COMPONENT "audio_devel")
-install(FILES ${gr_audio_confs} DESTINATION ${GR_PKG_CONF_DIR} COMPONENT "audio_runtime")
+install(FILES ${gr_audio_confs} DESTINATION ${GR_PREFSDIR} COMPONENT "audio_runtime")
diff --git a/gr-digital/examples/narrowband/digital_bert_rx.py b/gr-digital/examples/narrowband/digital_bert_rx.py
index ab7e988eba..daefc5116d 100755
--- a/gr-digital/examples/narrowband/digital_bert_rx.py
+++ b/gr-digital/examples/narrowband/digital_bert_rx.py
@@ -78,10 +78,10 @@ class bert_receiver(gr.hier_block2):
self.connect(self._demod.time_recov, self._snr_probe)
# Descramble BERT sequence. A channel error will create 3 incorrect bits
- self._descrambler = gr.descrambler_bb(0x8A, 0x7F, 7) # CCSDS 7-bit descrambler
+ self._descrambler = digital.descrambler_bb(0x8A, 0x7F, 7) # CCSDS 7-bit descrambler
# Measure BER by the density of 0s in the stream
- self._ber = gr.probe_density_b(1.0/self._symbol_rate)
+ self._ber = digital.probe_density_b(1.0/self._symbol_rate)
self.connect(self, self._demod, self._descrambler, self._ber)
diff --git a/gr-digital/examples/narrowband/digital_bert_tx.py b/gr-digital/examples/narrowband/digital_bert_tx.py
index f29e997af6..7caccdf42b 100755
--- a/gr-digital/examples/narrowband/digital_bert_tx.py
+++ b/gr-digital/examples/narrowband/digital_bert_tx.py
@@ -43,7 +43,7 @@ class bert_transmit(gr.hier_block2):
# Create BERT data bit stream
self._bits = gr.vector_source_b([1,], True) # Infinite stream of ones
- self._scrambler = gr.scrambler_bb(0x8A, 0x7F, 7) # CCSDS 7-bit scrambler
+ self._scrambler = digital.scrambler_bb(0x8A, 0x7F, 7) # CCSDS 7-bit scrambler
self._mod = digital.generic_mod(constellation, samples_per_symbol,
differential, excess_bw, gray_coded,
diff --git a/gr-digital/grc/digital_dxpsk_demod.xml b/gr-digital/grc/digital_dxpsk_demod.xml
index cfd474f68f..35704eeb67 100644
--- a/gr-digital/grc/digital_dxpsk_demod.xml
+++ b/gr-digital/grc/digital_dxpsk_demod.xml
@@ -23,7 +23,7 @@
<!--
###################################################
-##DPSK2 Mod - 2, 4, 8
+##DPSK2 Mod - 2, 4
###################################################
-->
<block>
@@ -36,7 +36,7 @@
freq_bw=$freq_bw,
phase_bw=$phase_bw,
timing_bw=$timing_bw,
- gray_coded=$gray_coded,
+ mod_code=$mod_code,
verbose=$verbose,
log=$log
)</make>
@@ -93,16 +93,15 @@
</param>
<param>
<name>Gray Code</name>
- <key>gray_coded</key>
- <value>True</value>
- <type>bool</type>
+ <key>mod_code</key>
+ <type>enum</type>
<option>
<name>Yes</name>
- <key>True</key>
+ <key>"gray"</key>
</option>
<option>
<name>No</name>
- <key>False</key>
+ <key>"none"</key>
</option>
</param>
<param>
diff --git a/gr-digital/grc/digital_dxpsk_mod.xml b/gr-digital/grc/digital_dxpsk_mod.xml
index fbda9fb1f9..060edb9081 100644
--- a/gr-digital/grc/digital_dxpsk_mod.xml
+++ b/gr-digital/grc/digital_dxpsk_mod.xml
@@ -23,7 +23,7 @@
<!--
###################################################
-## DPSK Mod - 2, 4, 8
+## DPSK Mod - 2, 4
###################################################
-->
<block>
@@ -33,7 +33,7 @@
<make>digital.$(type)_mod(
samples_per_symbol=$samples_per_symbol,
excess_bw=$excess_bw,
- gray_coded=$gray_coded,
+ mod_code=$mod_code,
verbose=$verbose,
log=$log)
</make>
@@ -49,10 +49,6 @@
<name>DQPSK</name>
<key>dqpsk</key>
</option>
- <option>
- <name>D8PSK</name>
- <key>d8psk</key>
- </option>
</param>
<param>
<name>Samples/Symbol</name>
@@ -68,16 +64,16 @@
</param>
<param>
<name>Gray Code</name>
- <key>gray_coded</key>
- <value>True</value>
- <type>bool</type>
+ <key>mod_code</key>
+ <value>"gray"</value>
+ <type>enum</type>
<option>
<name>Yes</name>
- <key>True</key>
+ <key>"gray"</key>
</option>
<option>
<name>No</name>
- <key>False</key>
+ <key>"none"</key>
</option>
</param>
<param>
diff --git a/gr-digital/grc/digital_mpsk_receiver_cc.xml b/gr-digital/grc/digital_mpsk_receiver_cc.xml
index ab7e5c2091..bd738fccc3 100644
--- a/gr-digital/grc/digital_mpsk_receiver_cc.xml
+++ b/gr-digital/grc/digital_mpsk_receiver_cc.xml
@@ -7,7 +7,7 @@
<block>
<name>MPSK Receiver</name>
<key>digital_mpsk_receiver_cc</key>
- <import>from gnuradio import digital</import>
+ <import>from gnuradio import digital;import cmath</import>
<make>digital.mpsk_receiver_cc($M, $theta, $w, $fmin, $fmax, $mu, $gain_mu, $omega, $gain_omega, $omega_relative_limit)</make>
<callback>set_loop_bandwidth($w)</callback>
<callback>set_mu($mu)</callback>
@@ -17,51 +17,61 @@
<param>
<name>M</name>
<key>M</key>
+ <value>4</value>
<type>int</type>
</param>
<param>
<name>Theta</name>
<key>theta</key>
+ <value>0</value>
<type>real</type>
</param>
<param>
<name>Loop Bandwidth</name>
<key>w</key>
+ <value>cmath.pi/100.0</value>
<type>real</type>
</param>
<param>
<name>Min Freq</name>
<key>fmin</key>
+ <value>-0.5</value>
<type>real</type>
</param>
<param>
<name>Max Freq</name>
<key>fmax</key>
+ <value>0.5</value>
<type>real</type>
</param>
<param>
<name>Mu</name>
<key>mu</key>
+ <value>0.25</value>
<type>real</type>
</param>
<param>
<name>Gain Mu</name>
<key>gain_mu</key>
+ <value>0.01</value>
<type>real</type>
</param>
<param>
<name>Omega</name>
<key>omega</key>
+ <value>2</value>
<type>real</type>
</param>
<param>
<name>Gain Omega</name>
<key>gain_omega</key>
+ <value>0.001</value>
<type>real</type>
</param>
<param>
<name>Omega Relative Limit</name>
<key>omega_relative_limit</key>
+ <value>0.001</value>
<type>real</type>
</param>
<sink>
@@ -72,4 +82,5 @@
<name>out</name>
<type>complex</type>
</source>
+
</block>
diff --git a/gr-digital/grc/digital_ofdm_insert_preamble.xml b/gr-digital/grc/digital_ofdm_insert_preamble.xml
index 33a93058f9..9ad8fa793b 100644
--- a/gr-digital/grc/digital_ofdm_insert_preamble.xml
+++ b/gr-digital/grc/digital_ofdm_insert_preamble.xml
@@ -48,10 +48,16 @@
<sink>
<name>flag</name>
<type>byte</type>
+ <optional>1</optional>
</sink>
<source>
<name>out</name>
<type>complex</type>
<vlen>$fft_length</vlen>
</source>
+ <source>
+ <name>flag</name>
+ <type>byte</type>
+ <optional>1</optional>
+ </source>
</block>
diff --git a/gr-digital/grc/digital_psk_demod.xml b/gr-digital/grc/digital_psk_demod.xml
index 7e0773a986..2e0e86ebc6 100644
--- a/gr-digital/grc/digital_psk_demod.xml
+++ b/gr-digital/grc/digital_psk_demod.xml
@@ -37,7 +37,7 @@
excess_bw=$excess_bw,
phase_bw=$phase_bw,
timing_bw=$timing_bw,
- gray_coded=$gray_coded,
+ mod_code=$mod_code,
verbose=$verbose,
log=$log,
)</make>
@@ -93,7 +93,7 @@
</param>
<param>
<name>Gray Code</name>
- <key>gray_coded</key>
+ <key>mod_code</key>
<type>enum</type>
<option>
<name>Yes</name>
diff --git a/gr-digital/grc/digital_qam_demod.xml b/gr-digital/grc/digital_qam_demod.xml
index 86080fff79..5aaec1bd0a 100644
--- a/gr-digital/grc/digital_qam_demod.xml
+++ b/gr-digital/grc/digital_qam_demod.xml
@@ -38,7 +38,7 @@
freq_bw=$freq_bw,
timing_bw=$timing_bw,
phase_bw=$phase_bw,
- gray_coded=$gray_coded,
+ mod_code=$mod_code,
verbose=$verbose,
log=$log,
)</make>
diff --git a/gr-digital/grc/digital_simple_framer.xml b/gr-digital/grc/digital_simple_framer.xml
index bbeed32d3e..2d57222f3b 100644
--- a/gr-digital/grc/digital_simple_framer.xml
+++ b/gr-digital/grc/digital_simple_framer.xml
@@ -7,8 +7,8 @@
<block>
<name>Simple Framer</name>
<key>digital_simple_framer</key>
- <import>from gnuradio import gr</import>
- <make>gr.simple_framer($payload_bytesize)</make>
+ <import>from gnuradio import digital</import>
+ <make>digital.simple_framer($payload_bytesize)</make>
<param>
<name>Payload Byte Size</name>
<key>payload_bytesize</key>
diff --git a/gr-digital/include/digital_bytes_to_syms.h b/gr-digital/include/digital_bytes_to_syms.h
index 3062366b95..c1857c8cf2 100644
--- a/gr-digital/include/digital_bytes_to_syms.h
+++ b/gr-digital/include/digital_bytes_to_syms.h
@@ -39,12 +39,12 @@ DIGITAL_API digital_bytes_to_syms_sptr digital_make_bytes_to_syms();
* 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
+ * digital_chunks_to_symbols_bf or digital_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.
+ * \sa digital_chunks_to_symbols_bf, digital_chunks_to_symbols_bc.
*/
class DIGITAL_API digital_bytes_to_syms : public gr_sync_interpolator
{
diff --git a/gr-digital/include/digital_chunks_to_symbols_XX.h.t b/gr-digital/include/digital_chunks_to_symbols_XX.h.t
index 92b7c94d58..3a82c68070 100644
--- a/gr-digital/include/digital_chunks_to_symbols_XX.h.t
+++ b/gr-digital/include/digital_chunks_to_symbols_XX.h.t
@@ -43,7 +43,7 @@ digital_make_@BASE_NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D
* 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
+ * digital_chunks_to_symbols_XY handles the general case of mapping
* from a stream of bytes or shorts into arbitrary float
* or complex symbols.
*
diff --git a/gr-digital/include/digital_framer_sink_1.h b/gr-digital/include/digital_framer_sink_1.h
index bb82bf5a73..51d872d874 100644
--- a/gr-digital/include/digital_framer_sink_1.h
+++ b/gr-digital/include/digital_framer_sink_1.h
@@ -37,7 +37,7 @@ digital_make_framer_sink_1(gr_msg_queue_sptr target_queue);
* \brief Given a stream of bits and access_code flags, assemble packets.
* \ingroup sink_blk
*
- * input: stream of bytes from gr_correlate_access_code_bb
+ * input: stream of bytes from digital_correlate_access_code_bb
* output: none. Pushes assembled packet into target queue
*
* The framer expects a fixed length header of 2 16-bit shorts
diff --git a/gr-digital/include/digital_glfsr_source_b.h b/gr-digital/include/digital_glfsr_source_b.h
index 92e5e81f5c..151e5a296c 100644
--- a/gr-digital/include/digital_glfsr_source_b.h
+++ b/gr-digital/include/digital_glfsr_source_b.h
@@ -26,7 +26,7 @@
#include <digital_api.h>
#include <gr_sync_block.h>
-class gri_glfsr;
+class digital_impl_glfsr;
class digital_glfsr_source_b;
typedef boost::shared_ptr<digital_glfsr_source_b> digital_glfsr_source_b_sptr;
@@ -54,7 +54,7 @@ class DIGITAL_API digital_glfsr_source_b : public gr_sync_block
digital_make_glfsr_source_b(int degree, bool repeat,
int mask, int seed);
- gri_glfsr *d_glfsr;
+ digital_impl_glfsr *d_glfsr;
bool d_repeat;
unsigned int d_index;
diff --git a/gr-digital/include/digital_glfsr_source_f.h b/gr-digital/include/digital_glfsr_source_f.h
index 77d7b0f741..fb5b064e4f 100644
--- a/gr-digital/include/digital_glfsr_source_f.h
+++ b/gr-digital/include/digital_glfsr_source_f.h
@@ -26,7 +26,7 @@
#include <digital_api.h>
#include <gr_sync_block.h>
-class gri_glfsr;
+class digital_impl_glfsr;
class digital_glfsr_source_f;
typedef boost::shared_ptr<digital_glfsr_source_f> digital_glfsr_source_f_sptr;
@@ -54,7 +54,7 @@ class DIGITAL_API digital_glfsr_source_f : public gr_sync_block
digital_make_glfsr_source_f(int degree, bool repeat,
int mask, int seed);
- gri_glfsr *d_glfsr;
+ digital_impl_glfsr *d_glfsr;
bool d_repeat;
unsigned int d_index;
diff --git a/gr-digital/include/digital_ofdm_insert_preamble.h b/gr-digital/include/digital_ofdm_insert_preamble.h
index 6f9dae5d6b..fa44558add 100644
--- a/gr-digital/include/digital_ofdm_insert_preamble.h
+++ b/gr-digital/include/digital_ofdm_insert_preamble.h
@@ -88,18 +88,20 @@ private:
int d_pending_flag;
void enter_idle();
- void enter_preamble();
void enter_first_payload();
void enter_payload();
public:
~digital_ofdm_insert_preamble();
+ void enter_preamble();
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 forecast (int noutput_items, gr_vector_int &ninput_items_required);
+
};
#endif /* INCLUDED_DIGITAL_OFDM_INSERT_PREAMBLE_H */
diff --git a/gr-digital/include/digital_pn_correlator_cc.h b/gr-digital/include/digital_pn_correlator_cc.h
index 87cc2ff93c..407cc1e67b 100644
--- a/gr-digital/include/digital_pn_correlator_cc.h
+++ b/gr-digital/include/digital_pn_correlator_cc.h
@@ -25,7 +25,7 @@
#include <digital_api.h>
#include <gr_sync_decimator.h>
-#include <gri_glfsr.h>
+#include <digital_impl_glfsr.h>
class digital_pn_correlator_cc;
typedef boost::shared_ptr<digital_pn_correlator_cc> digital_pn_correlator_cc_sptr;
@@ -56,7 +56,7 @@ class DIGITAL_API digital_pn_correlator_cc : public gr_sync_decimator
int d_len;
float d_pn;
- gri_glfsr *d_reference;
+ digital_impl_glfsr *d_reference;
protected:
digital_pn_correlator_cc(int degree, int mask, int seed);
diff --git a/gr-digital/lib/digital_constellation.cc b/gr-digital/lib/digital_constellation.cc
index d9a53c4930..383c73c30d 100644
--- a/gr-digital/lib/digital_constellation.cc
+++ b/gr-digital/lib/digital_constellation.cc
@@ -466,8 +466,8 @@ digital_make_constellation_dqpsk()
digital_constellation_dqpsk::digital_constellation_dqpsk ()
{
// This constellation is not gray coded, which allows
- // us to use differential encodings (through gr_diff_encode and
- // gr_diff_decode) on the symbols.
+ // us to use differential encodings (through digital_diff_encode and
+ // digital_diff_decode) on the symbols.
d_constellation.resize(4);
d_constellation[0] = gr_complex(+SQRT_TWO, +SQRT_TWO);
d_constellation[1] = gr_complex(-SQRT_TWO, +SQRT_TWO);
diff --git a/gr-digital/lib/digital_glfsr_source_b.cc b/gr-digital/lib/digital_glfsr_source_b.cc
index e557e475a8..63a5ffdb0a 100644
--- a/gr-digital/lib/digital_glfsr_source_b.cc
+++ b/gr-digital/lib/digital_glfsr_source_b.cc
@@ -26,7 +26,7 @@
#endif
#include <digital_glfsr_source_b.h>
-#include <gri_glfsr.h>
+#include <digital_impl_glfsr.h>
#include <gr_io_signature.h>
#include <stdexcept>
@@ -50,8 +50,8 @@ digital_glfsr_source_b::digital_glfsr_source_b(int degree, bool repeat,
d_length = (unsigned int)((1ULL << degree)-1);
if (mask == 0)
- mask = gri_glfsr::glfsr_mask(degree);
- d_glfsr = new gri_glfsr(mask, seed);
+ mask = digital_impl_glfsr::glfsr_mask(degree);
+ d_glfsr = new digital_impl_glfsr(mask, seed);
}
digital_glfsr_source_b::~digital_glfsr_source_b()
diff --git a/gr-digital/lib/digital_glfsr_source_f.cc b/gr-digital/lib/digital_glfsr_source_f.cc
index 5a7736ef8d..6ae84d5679 100644
--- a/gr-digital/lib/digital_glfsr_source_f.cc
+++ b/gr-digital/lib/digital_glfsr_source_f.cc
@@ -26,7 +26,7 @@
#endif
#include <digital_glfsr_source_f.h>
-#include <gri_glfsr.h>
+#include <digital_impl_glfsr.h>
#include <gr_io_signature.h>
#include <stdexcept>
@@ -50,8 +50,8 @@ digital_glfsr_source_f::digital_glfsr_source_f(int degree, bool repeat,
d_length = (unsigned int)((1ULL << degree)-1);
if (mask == 0)
- mask = gri_glfsr::glfsr_mask(degree);
- d_glfsr = new gri_glfsr(mask, seed);
+ mask = digital_impl_glfsr::glfsr_mask(degree);
+ d_glfsr = new digital_impl_glfsr(mask, seed);
}
digital_glfsr_source_f::~digital_glfsr_source_f()
diff --git a/gr-digital/lib/digital_ofdm_insert_preamble.cc b/gr-digital/lib/digital_ofdm_insert_preamble.cc
index a46133643d..72b9e82a82 100644
--- a/gr-digital/lib/digital_ofdm_insert_preamble.cc
+++ b/gr-digital/lib/digital_ofdm_insert_preamble.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2007,2010,2011 Free Software Foundation, Inc.
+ * Copyright 2007,2010-2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -41,7 +41,7 @@ digital_ofdm_insert_preamble::digital_ofdm_insert_preamble
(int fft_length,
const std::vector<std::vector<gr_complex> > &preamble)
: gr_block("ofdm_insert_preamble",
- gr_make_io_signature2(2, 2,
+ gr_make_io_signature2(1, 2,
sizeof(gr_complex)*fft_length,
sizeof(char)),
gr_make_io_signature2(1, 2,
@@ -54,8 +54,8 @@ digital_ofdm_insert_preamble::digital_ofdm_insert_preamble
d_pending_flag(0)
{
// sanity check preamble symbols
- for (size_t i = 0; i < d_preamble.size(); i++){
- if (d_preamble[i].size() != (size_t) d_fft_length)
+ for(size_t i = 0; i < d_preamble.size(); i++) {
+ if(d_preamble[i].size() != (size_t) d_fft_length)
throw std::invalid_argument("digital_ofdm_insert_preamble: invalid length for preamble symbol");
}
@@ -67,15 +67,22 @@ digital_ofdm_insert_preamble::~digital_ofdm_insert_preamble()
{
}
+void digital_ofdm_insert_preamble::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+ ninput_items_required[0] = noutput_items;
+}
+
int
-digital_ofdm_insert_preamble::general_work (int noutput_items,
- gr_vector_int &ninput_items_v,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
+digital_ofdm_insert_preamble::general_work(int noutput_items,
+ gr_vector_int &ninput_items_v,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
{
- int ninput_items = std::min(ninput_items_v[0], ninput_items_v[1]);
+ int ninput_items = ninput_items_v.size()==2?std::min(ninput_items_v[0], ninput_items_v[1]):ninput_items_v[0];
const gr_complex *in_sym = (const gr_complex *) input_items[0];
- const unsigned char *in_flag = (const unsigned char *) input_items[1];
+ const unsigned char *in_flag = 0;
+ if (input_items.size() == 2)
+ in_flag = (const unsigned char *) input_items[1];
gr_complex *out_sym = (gr_complex *) output_items[0];
unsigned char *out_flag = 0;
@@ -97,14 +104,14 @@ digital_ofdm_insert_preamble::general_work (int noutput_items,
while (no < noutput_items && ni < ninput_items){
switch(d_state){
case ST_IDLE:
- if (in_flag[ni] & 0x1) // this is first symbol of new payload
+ if (in_flag && in_flag[ni] & 0x1) // this is first symbol of new payload
enter_preamble();
else
ni++; // eat one input symbol
break;
case ST_PREAMBLE:
- assert(in_flag[ni] & 0x1);
+ assert(!in_flag || in_flag[ni] & 0x1);
if (d_nsymbols_output >= (int) d_preamble.size()){
// we've output all the preamble
enter_first_payload();
@@ -133,7 +140,7 @@ digital_ofdm_insert_preamble::general_work (int noutput_items,
break;
case ST_PAYLOAD:
- if (in_flag[ni] & 0x1){ // this is first symbol of a new payload
+ if (in_flag && in_flag[ni] & 0x1){ // this is first symbol of a new payload
enter_preamble();
break;
}
diff --git a/gr-digital/lib/digital_pn_correlator_cc.cc b/gr-digital/lib/digital_pn_correlator_cc.cc
index 43a3ddbd1f..52e06bc2ad 100644
--- a/gr-digital/lib/digital_pn_correlator_cc.cc
+++ b/gr-digital/lib/digital_pn_correlator_cc.cc
@@ -44,8 +44,8 @@ digital_pn_correlator_cc::digital_pn_correlator_cc(int degree,
{
d_len = (unsigned int)((1ULL << degree)-1);
if (mask == 0)
- mask = gri_glfsr::glfsr_mask(degree);
- d_reference = new gri_glfsr(mask, seed);
+ mask = digital_impl_glfsr::glfsr_mask(degree);
+ d_reference = new digital_impl_glfsr(mask, seed);
for (int i = 0; i < d_len; i++) // initialize to last value in sequence
d_pn = 2.0*d_reference->next_bit()-1.0;
}
diff --git a/gr-digital/python/bpsk.py b/gr-digital/python/bpsk.py
index 0d8f05c4c1..9f2354003c 100644
--- a/gr-digital/python/bpsk.py
+++ b/gr-digital/python/bpsk.py
@@ -31,18 +31,11 @@ from gnuradio.digital.generic_mod_demod import generic_mod, generic_demod
import digital_swig
import modulation_utils
-# Default number of points in constellation.
-_def_constellation_points = 2
-# Whether differential coding is used.
-_def_differential = False
-
# /////////////////////////////////////////////////////////////////////////////
# BPSK constellation
# /////////////////////////////////////////////////////////////////////////////
-def bpsk_constellation(m=_def_constellation_points):
- if m != _def_constellation_points:
- raise ValueError("BPSK can only have 2 constellation points.")
+def bpsk_constellation():
return digital_swig.constellation_bpsk()
# /////////////////////////////////////////////////////////////////////////////
@@ -51,8 +44,7 @@ def bpsk_constellation(m=_def_constellation_points):
class bpsk_mod(generic_mod):
- def __init__(self, constellation_points=_def_constellation_points,
- differential=False, *args, **kwargs):
+ def __init__(self, mod_code=None, differential=False, *args, **kwargs):
"""
Hierarchical block for RRC-filtered BPSK modulation.
@@ -61,12 +53,12 @@ class bpsk_mod(generic_mod):
output is the complex modulated signal at baseband.
See generic_mod block for list of parameters.
+
+ 'mod_code' argument is not used.
+ It exists purely to simplify generation of the block in grc.
"""
- constellation_points = _def_constellation_points
constellation = digital_swig.constellation_bpsk()
- if constellation_points != 2:
- raise ValueError('Number of constellation points must be 2 for BPSK.')
super(bpsk_mod, self).__init__(constellation=constellation,
differential=differential, *args, **kwargs)
@@ -77,8 +69,7 @@ class bpsk_mod(generic_mod):
class bpsk_demod(generic_demod):
- def __init__(self, constellation_points=_def_constellation_points,
- differential=False, *args, **kwargs):
+ def __init__(self, mod_code=None, differential=False, *args, **kwargs):
"""
Hierarchical block for RRC-filtered BPSK modulation.
@@ -87,12 +78,12 @@ class bpsk_demod(generic_demod):
output is the complex modulated signal at baseband.
See generic_demod block for list of parameters.
+
+ 'mod_code' argument is not used.
+ It exists purely to simplify generation of the block in grc.
"""
- constellation_points = _def_constellation_points
constellation = digital_swig.constellation_bpsk()
- if constellation_points != 2:
- raise ValueError('Number of constellation points must be 2 for BPSK.')
super(bpsk_demod, self).__init__(constellation=constellation,
differential=differential, *args, **kwargs)
@@ -102,19 +93,16 @@ class bpsk_demod(generic_demod):
# DBPSK constellation
# /////////////////////////////////////////////////////////////////////////////
-def dbpsk_constellation(m=_def_constellation_points):
- if m != _def_constellation_points:
- raise ValueError("DBPSK can only have 2 constellation points.")
+def dbpsk_constellation():
return digital_swig.constellation_dbpsk()
# /////////////////////////////////////////////////////////////////////////////
# DBPSK modulator
# /////////////////////////////////////////////////////////////////////////////
-class dbpsk_mod(generic_mod):
+class dbpsk_mod(bpsk_mod):
- def __init__(self, constellation_points=_def_constellation_points,
- differential=True, *args, **kwargs):
+ def __init__(self, mod_code=None, *args, **kwargs):
"""
Hierarchical block for RRC-filtered DBPSK modulation.
@@ -123,14 +111,12 @@ class dbpsk_mod(generic_mod):
output is the complex modulated signal at baseband.
See generic_mod block for list of parameters.
+
+ 'mod_code' argument is not used.
+ It exists purely to simplify generation of the block in grc.
"""
- constellation_points = _def_constellation_points
- constellation = digital_swig.constellation_bpsk()
- if constellation_points != 2:
- raise ValueError('Number of constellation points must be 2 for DBPSK.')
- super(dbpsk_mod, self).__init__(constellation=constellation,
- differential=True,
+ super(dbpsk_mod, self).__init__(differential=True,
*args, **kwargs)
# /////////////////////////////////////////////////////////////////////////////
@@ -138,10 +124,9 @@ class dbpsk_mod(generic_mod):
#
# /////////////////////////////////////////////////////////////////////////////
-class dbpsk_demod(generic_demod):
+class dbpsk_demod(bpsk_demod):
- def __init__(self, constellation_points=_def_constellation_points,
- differential=True, *args, **kwargs):
+ def __init__(self, mod_code=None, *args, **kwargs):
"""
Hierarchical block for RRC-filtered DBPSK modulation.
@@ -150,14 +135,12 @@ class dbpsk_demod(generic_demod):
output is the complex modulated signal at baseband.
See generic_demod block for list of parameters.
+
+ 'mod_code' argument is not used.
+ It exists purely to simplify generation of the block in grc.
"""
- constellation_points = _def_constellation_points
- constellation = digital_swig.constellation_bpsk()
- if constellation_points != 2:
- raise ValueError('Number of constellation points must be 2 for DBPSK.')
- super(dbpsk_demod, self).__init__(constellation=constellation,
- differential=True,
+ super(dbpsk_demod, self).__init__(differential=True,
*args, **kwargs)
#
diff --git a/gr-digital/python/cpm.py b/gr-digital/python/cpm.py
index 05032336d4..f11832b626 100644
--- a/gr-digital/python/cpm.py
+++ b/gr-digital/python/cpm.py
@@ -131,7 +131,7 @@ class cpm_mod(gr.hier_block2):
# Turn it into symmetric PAM data.
- self.pam = gr.chunks_to_symbols_bf(self.sym_alphabet,1)
+ self.pam = digital_swig.chunks_to_symbols_bf(self.sym_alphabet,1)
# Generate pulse (sum of taps = samples_per_symbol/2)
if cpm_type == 0: # CPFSK
diff --git a/gr-digital/python/generic_mod_demod.py b/gr-digital/python/generic_mod_demod.py
index a6c4f3445a..105c6fe8ff 100644
--- a/gr-digital/python/generic_mod_demod.py
+++ b/gr-digital/python/generic_mod_demod.py
@@ -76,10 +76,10 @@ def add_common_options(parser):
class generic_mod(gr.hier_block2):
def __init__(self, constellation,
- samples_per_symbol=_def_samples_per_symbol,
differential=_def_differential,
+ samples_per_symbol=_def_samples_per_symbol,
+ pre_diff_code=True,
excess_bw=_def_excess_bw,
- gray_coded=True,
verbose=_def_verbose,
log=_def_log):
"""
@@ -92,10 +92,12 @@ class generic_mod(gr.hier_block2):
@type constellation: gnuradio.digital.gr_constellation
@param samples_per_symbol: samples per baud >= 2
@type samples_per_symbol: float
+ @param differential: whether to use differential encoding
+ @type differential: boolean
+ @param pre_diff_code: whether to use apply a pre-differential mapping
+ @type pre_diff_code: boolean
@param excess_bw: Root-raised cosine filter excess bandwidth
@type excess_bw: float
- @param gray_coded: turn gray coding on/off
- @type gray_coded: bool
@param verbose: Print information about modulator?
@type verbose: bool
@param log: Log modulation data to files?
@@ -110,6 +112,8 @@ class generic_mod(gr.hier_block2):
self._samples_per_symbol = samples_per_symbol
self._excess_bw = excess_bw
self._differential = differential
+ # Only apply a predifferential coding if the constellation also supports it.
+ self.pre_diff_code = pre_diff_code and self._constellation.apply_pre_diff_code()
if self._samples_per_symbol < 2:
raise TypeError, ("sbp must be >= 2, is %f" % self._samples_per_symbol)
@@ -120,7 +124,7 @@ class generic_mod(gr.hier_block2):
self.bytes2chunks = \
gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST)
- if gray_coded == True:
+ if self.pre_diff_code:
self.symbol_mapper = digital.map_bb(self._constellation.pre_diff_code())
if differential:
@@ -142,7 +146,7 @@ class generic_mod(gr.hier_block2):
# Connect
blocks = [self, self.bytes2chunks]
- if gray_coded == True:
+ if self.pre_diff_code:
blocks.append(self.symbol_mapper)
if differential:
blocks.append(self.diffenc)
@@ -186,7 +190,7 @@ class generic_mod(gr.hier_block2):
print "Modulation logging turned on."
self.connect(self.bytes2chunks,
gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.8b"))
- if self._constellation.apply_pre_diff_code():
+ if self.pre_diff_code:
self.connect(self.symbol_mapper,
gr.file_sink(gr.sizeof_char, "tx_symbol_mapper.8b"))
if self._differential:
@@ -208,10 +212,10 @@ class generic_mod(gr.hier_block2):
class generic_demod(gr.hier_block2):
def __init__(self, constellation,
- samples_per_symbol=_def_samples_per_symbol,
differential=_def_differential,
+ samples_per_symbol=_def_samples_per_symbol,
+ pre_diff_code=True,
excess_bw=_def_excess_bw,
- gray_coded=True,
freq_bw=_def_freq_bw,
timing_bw=_def_timing_bw,
phase_bw=_def_phase_bw,
@@ -227,10 +231,12 @@ class generic_demod(gr.hier_block2):
@type constellation: gnuradio.digital.gr_constellation
@param samples_per_symbol: samples per symbol >= 2
@type samples_per_symbol: float
+ @param differential: whether to use differential encoding
+ @type differential: boolean
+ @param pre_diff_code: whether to use apply a pre-differential mapping
+ @type pre_diff_code: boolean
@param excess_bw: Root-raised cosine filter excess bandwidth
@type excess_bw: float
- @param gray_coded: turn gray coding on/off
- @type gray_coded: bool
@param freq_bw: loop filter lock-in bandwidth
@type freq_bw: float
@param timing_bw: timing recovery loop lock-in bandwidth
@@ -259,6 +265,9 @@ class generic_demod(gr.hier_block2):
if self._samples_per_symbol < 2:
raise TypeError, ("sbp must be >= 2, is %d" % self._samples_per_symbol)
+ # Only apply a predifferential coding if the constellation also supports it.
+ self.pre_diff_code = pre_diff_code and self._constellation.apply_pre_diff_code()
+
arity = pow(2,self.bits_per_symbol())
nfilts = 32
@@ -289,7 +298,7 @@ class generic_demod(gr.hier_block2):
if differential:
self.diffdec = digital.diff_decoder_bb(arity)
- if gray_coded:
+ if self.pre_diff_code:
self.symbol_mapper = digital.map_bb(
mod_codes.invert_code(self._constellation.pre_diff_code()))
@@ -307,7 +316,7 @@ class generic_demod(gr.hier_block2):
self.time_recov, self.receiver]
if differential:
blocks.append(self.diffdec)
- if self._constellation.apply_pre_diff_code():
+ if self.pre_diff_code:
blocks.append(self.symbol_mapper)
blocks += [self.unpack, self]
self.connect(*blocks)
@@ -357,7 +366,7 @@ class generic_demod(gr.hier_block2):
if self._differential:
self.connect(self.diffdec,
gr.file_sink(gr.sizeof_char, "rx_diffdec.8b"))
- if self._constellation.apply_pre_diff_code():
+ if self.pre_diff_code:
self.connect(self.symbol_mapper,
gr.file_sink(gr.sizeof_char, "rx_symbol_mapper.8b"))
self.connect(self.unpack,
diff --git a/gr-digital/python/pkt.py b/gr-digital/python/pkt.py
index 8650bdbb02..09254a7caa 100644
--- a/gr-digital/python/pkt.py
+++ b/gr-digital/python/pkt.py
@@ -143,7 +143,7 @@ class demod_pkts(gr.hier_block2):
self._rcvd_pktq = gr.msg_queue() # holds packets from the PHY
self.correlator = digital_swig.correlate_access_code_bb(access_code, threshold)
- self.framer_sink = gr.framer_sink_1(self._rcvd_pktq)
+ self.framer_sink = digital.framer_sink_1(self._rcvd_pktq)
self.connect(self, self._demodulator, self.correlator, self.framer_sink)
self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback)
diff --git a/gr-digital/python/psk.py b/gr-digital/python/psk.py
index 58f6787f0c..4b35447278 100644
--- a/gr-digital/python/psk.py
+++ b/gr-digital/python/psk.py
@@ -35,17 +35,23 @@ from generic_mod_demod import generic_mod, generic_demod
_def_constellation_points = 4
# The default encoding (e.g. gray-code, set-partition)
_def_mod_code = mod_codes.GRAY_CODE
+# Default use of differential encoding
+_def_differential = True
-def create_encodings(mod_code, arity):
+def create_encodings(mod_code, arity, differential):
post_diff_code = None
if mod_code not in mod_codes.codes:
raise ValueError('That modulation code does not exist.')
if mod_code == mod_codes.GRAY_CODE:
- pre_diff_code = gray_code.gray_code(arity)
- elif mod_code == mod_codes.SET_PARTITION_CODE:
- pre_diff_code = set_partition_code.set_partition_code(arity)
+ if differential:
+ pre_diff_code = gray_code.gray_code(arity)
+ post_diff_code = None
+ else:
+ pre_diff_code = []
+ post_diff_code = gray_code.gray_code(arity)
elif mod_code == mod_codes.NO_CODE:
pre_diff_code = []
+ post_diff_code = None
else:
raise ValueError('That modulation code is not implemented for this constellation.')
return (pre_diff_code, post_diff_code)
@@ -54,7 +60,8 @@ def create_encodings(mod_code, arity):
# PSK constellation
# /////////////////////////////////////////////////////////////////////////////
-def psk_constellation(m=_def_constellation_points, mod_code=_def_mod_code):
+def psk_constellation(m=_def_constellation_points, mod_code=_def_mod_code,
+ differential=_def_differential):
"""
Creates a PSK constellation object.
"""
@@ -62,7 +69,7 @@ def psk_constellation(m=_def_constellation_points, mod_code=_def_mod_code):
if (k != int(k)):
raise StandardError('Number of constellation points must be a power of two.')
points = [exp(2*pi*(0+1j)*i/m) for i in range(0,m)]
- pre_diff_code, post_diff_code = create_encodings(mod_code, m)
+ pre_diff_code, post_diff_code = create_encodings(mod_code, m, differential)
if post_diff_code is not None:
inverse_post_diff_code = mod_codes.invert_code(post_diff_code)
points = [points[x] for x in inverse_post_diff_code]
@@ -77,6 +84,7 @@ class psk_mod(generic_mod):
def __init__(self, constellation_points=_def_constellation_points,
mod_code=_def_mod_code,
+ differential=_def_differential,
*args, **kwargs):
"""
@@ -88,8 +96,8 @@ class psk_mod(generic_mod):
See generic_mod block for list of parameters.
"""
- constellation = psk_constellation(constellation_points, mod_code)
- super(psk_mod, self).__init__(constellation, *args, **kwargs)
+ constellation = psk_constellation(constellation_points, mod_code, differential)
+ super(psk_mod, self).__init__(constellation, differential, *args, **kwargs)
# /////////////////////////////////////////////////////////////////////////////
# PSK demodulator
@@ -100,6 +108,7 @@ class psk_demod(generic_demod):
def __init__(self, constellation_points=_def_constellation_points,
mod_code=_def_mod_code,
+ differential=_def_differential,
*args, **kwargs):
"""
@@ -111,8 +120,8 @@ class psk_demod(generic_demod):
See generic_demod block for list of parameters.
"""
- constellation = psk_constellation(constellation_points, mod_code)
- super(psk_demod, self).__init__(constellation, *args, **kwargs)
+ constellation = psk_constellation(constellation_points, mod_code, differential)
+ super(psk_demod, self).__init__(constellation, differential, *args, **kwargs)
#
# Add these to the mod/demod registry
diff --git a/gr-digital/python/qa_constellation.py b/gr-digital/python/qa_constellation.py
index b17d2a0fcb..e0b5b3888e 100755
--- a/gr-digital/python/qa_constellation.py
+++ b/gr-digital/python/qa_constellation.py
@@ -67,8 +67,24 @@ def threed_constell():
tested_constellation_info = (
(psk.psk_constellation,
{'m': (2, 4, 8, 16, 32, 64),
- 'mod_code': tested_mod_codes, },
+ 'mod_code': tested_mod_codes,
+ 'differential': (True,)},
True, None),
+ (psk.psk_constellation,
+ {'m': (2, 4, 8, 16, 32, 64),
+ 'mod_code': tested_mod_codes,
+ 'differential': (False,)},
+ False, None),
+ (qam.qam_constellation,
+ {'constellation_points': (4, 16, 64),
+ 'mod_code': tested_mod_codes,
+ 'differential': (True,)},
+ True, None),
+ (qam.qam_constellation,
+ {'constellation_points': (4, 16, 64),
+ 'mod_code': tested_mod_codes,
+ 'differential': (False,)},
+ False, None),
(digital_swig.constellation_bpsk, {}, True, None),
(digital_swig.constellation_qpsk, {}, False, None),
(digital_swig.constellation_dqpsk, {}, True, None),
@@ -167,13 +183,13 @@ class mod_demod(gr.hier_block2):
# Apply any pre-differential coding
# Gray-coding is done here if we're also using differential coding.
if self.constellation.apply_pre_diff_code():
- self.blocks.append(gr.map_bb(self.constellation.pre_diff_code()))
+ self.blocks.append(digital_swig.map_bb(self.constellation.pre_diff_code()))
# Differential encoding.
if self.differential:
- self.blocks.append(gr.diff_encoder_bb(arity))
+ self.blocks.append(digital_swig.diff_encoder_bb(arity))
# Convert to constellation symbols.
- self.blocks.append(gr.chunks_to_symbols_bc(self.constellation.points(),
- self.constellation.dimensionality()))
+ self.blocks.append(digital_swig.chunks_to_symbols_bc(self.constellation.points(),
+ self.constellation.dimensionality()))
# CHANNEL
# Channel just consists of a rotation to check differential coding.
if rotation is not None:
@@ -184,10 +200,10 @@ class mod_demod(gr.hier_block2):
self.blocks.append(digital_swig.constellation_decoder_cb(self.constellation.base()))
# Differential decoding.
if self.differential:
- self.blocks.append(gr.diff_decoder_bb(arity))
+ self.blocks.append(digital_swig.diff_decoder_bb(arity))
# Decode any pre-differential coding.
if self.constellation.apply_pre_diff_code():
- self.blocks.append(gr.map_bb(
+ self.blocks.append(digital_swig.map_bb(
mod_codes.invert_code(self.constellation.pre_diff_code())))
# unpack the k bit vector into a stream of bits
self.blocks.append(gr.unpack_k_bits_bb(
diff --git a/gr-digital/python/qa_constellation_receiver.py b/gr-digital/python/qa_constellation_receiver.py
index 2d25433b92..8c2d2da0c5 100755
--- a/gr-digital/python/qa_constellation_receiver.py
+++ b/gr-digital/python/qa_constellation_receiver.py
@@ -85,11 +85,16 @@ class test_constellation_receiver (gr_unittest.TestCase):
# That is not implemented since the receiver has no way of
# knowing where the beginning of a symbol is.
# It also doesn't work for non-differential modulation.
- if constellation.dimensionality() != 1 or not differential:
+ if constellation.dimensionality() != 1:
continue
data_length = DATA_LENGTH * constellation.bits_per_symbol()
+ if differential:
+ freq_offset=True
+ else:
+ freq_offset=False
tb = rec_test_tb(constellation, differential,
- src_data=self.src_data[:data_length])
+ src_data=self.src_data[:data_length],
+ freq_offset=freq_offset)
tb.run()
data = tb.dst.data()
d1 = tb.src_data[:int(len(tb.src_data)*self.ignore_fraction)]
@@ -105,12 +110,14 @@ class rec_test_tb (gr.top_block):
and generic demodulation.
"""
def __init__(self, constellation, differential,
- data_length=None, src_data=None):
+ data_length=None, src_data=None, freq_offset=True):
"""
- constellation -- a constellation object
- differential -- whether differential encoding is used
- data_length -- the number of bits of data to use
- src_data -- a list of the bits to use
+ Args:
+ constellation: a constellation object
+ differential: whether differential encoding is used
+ data_length: the number of bits of data to use
+ src_data: a list of the bits to use
+ freq_offset: whether to use a frequency offset in the channel
"""
super(rec_test_tb, self).__init__()
# Transmission Blocks
@@ -122,11 +129,18 @@ class rec_test_tb (gr.top_block):
src = gr.vector_source_b(self.src_data)
mod = generic_mod(constellation, differential=differential)
# Channel
- channel = gr.channel_model(NOISE_VOLTAGE, FREQUENCY_OFFSET, TIMING_OFFSET)
+ if freq_offset:
+ channel = gr.channel_model(NOISE_VOLTAGE, FREQUENCY_OFFSET, TIMING_OFFSET)
+ else:
+ channel = gr.channel_model(NOISE_VOLTAGE, 0, TIMING_OFFSET)
# Receiver Blocks
- demod = generic_demod(constellation, differential=differential,
- freq_bw=FREQ_BW,
- phase_bw=PHASE_BW)
+ if freq_offset:
+ demod = generic_demod(constellation, differential=differential,
+ freq_bw=FREQ_BW,
+ phase_bw=PHASE_BW)
+ else:
+ demod = generic_demod(constellation, differential=differential,
+ freq_bw=0, phase_bw=0)
self.dst = gr.vector_sink_b()
self.connect(src, packer, mod, channel, demod, self.dst)
diff --git a/gr-digital/python/qa_glfsr_source.py b/gr-digital/python/qa_glfsr_source.py
index 157520d7f8..7d02037335 100755
--- a/gr-digital/python/qa_glfsr_source.py
+++ b/gr-digital/python/qa_glfsr_source.py
@@ -38,9 +38,9 @@ class test_glfsr_source(gr_unittest.TestCase):
def test_001_degree_b(self):
self.assertRaises(RuntimeError,
- lambda: gr.glfsr_source_b(0))
+ lambda: digital.glfsr_source_b(0))
self.assertRaises(RuntimeError,
- lambda: gr.glfsr_source_b(33))
+ lambda: digital.glfsr_source_b(33))
def test_002_correlation_b(self):
for degree in range(1,11): # Higher degrees take too long to correlate
@@ -65,9 +65,9 @@ class test_glfsr_source(gr_unittest.TestCase):
def test_004_degree_f(self):
self.assertRaises(RuntimeError,
- lambda: gr.glfsr_source_f(0))
+ lambda: digital.glfsr_source_f(0))
self.assertRaises(RuntimeError,
- lambda: gr.glfsr_source_f(33))
+ lambda: digital.glfsr_source_f(33))
def test_005_correlation_f(self):
for degree in range(1,11): # Higher degrees take too long to correlate
src = digital.glfsr_source_f(degree, False)
diff --git a/gr-digital/python/qam.py b/gr-digital/python/qam.py
index 5b1f7683b8..0635fda75e 100644
--- a/gr-digital/python/qam.py
+++ b/gr-digital/python/qam.py
@@ -157,14 +157,20 @@ def qam_constellation(constellation_points=_def_constellation_points,
else:
raise ValueError("Mod code is not implemented for QAM")
if differential:
- points = make_differential_constellation(constellation_points, gray_coded)
+ points = make_differential_constellation(constellation_points, gray_coded=False)
else:
points = make_non_differential_constellation(constellation_points, gray_coded)
side = int(sqrt(constellation_points))
width = 2.0/(side-1)
- # No pre-diff code
- # Should add one so that we can gray-code the quadrant bits too.
- pre_diff_code = []
+ # For differential and gray-coded then gray-code the first two
+ # bits with a pre_diff_code.
+ # FIXME: It would be good to have a test to make sure that gray-coded constellations
+ # are really gray-coded. Perhaps by checking on the correlation between bit-errors.
+ if differential and gray_coded:
+ m = constellation_points
+ pre_diff_code = range(0, m/2) + range(3*m/4, m) + range(m/2, 3*m/4)
+ else:
+ pre_diff_code = []
constellation = digital_swig.constellation_rect(points, pre_diff_code, 4,
side, side, width, width)
return constellation
diff --git a/gr-digital/python/qpsk.py b/gr-digital/python/qpsk.py
index be21fd76f1..2fdeabd40f 100644
--- a/gr-digital/python/qpsk.py
+++ b/gr-digital/python/qpsk.py
@@ -27,21 +27,20 @@ Demodulation is not included since the generic_mod_demod
from gnuradio import gr
from gnuradio.digital.generic_mod_demod import generic_mod, generic_demod
+from utils import mod_codes
import digital_swig
import modulation_utils
-# Default number of points in constellation.
-_def_constellation_points = 4
-# Whether gray coding is used.
-_def_gray_coded = True
+# The default encoding (e.g. gray-code, set-partition)
+_def_mod_code = mod_codes.GRAY_CODE
# /////////////////////////////////////////////////////////////////////////////
# QPSK constellation
# /////////////////////////////////////////////////////////////////////////////
-def qpsk_constellation(m=_def_constellation_points):
- if m != _def_constellation_points:
- raise ValueError("QPSK can only have 4 constellation points.")
+def qpsk_constellation(mod_code=_def_mod_code):
+ if mod_code != mod_codes.GRAY_CODE:
+ raise ValueError("This QPSK mod/demod works only for gray-coded constellations.")
return digital_swig.constellation_qpsk()
# /////////////////////////////////////////////////////////////////////////////
@@ -50,9 +49,7 @@ def qpsk_constellation(m=_def_constellation_points):
class qpsk_mod(generic_mod):
- def __init__(self, constellation_points=_def_constellation_points,
- gray_coded=_def_gray_coded,
- *args, **kwargs):
+ def __init__(self, mod_code=_def_mod_code, differential=False, *args, **kwargs):
"""
Hierarchical block for RRC-filtered QPSK modulation.
@@ -62,15 +59,21 @@ class qpsk_mod(generic_mod):
See generic_mod block for list of parameters.
"""
-
- constellation_points = _def_constellation_points
- constellation = digital_swig.constellation_qpsk()
- if constellation_points != 4:
- raise ValueError("QPSK can only have 4 constellation points.")
- if not gray_coded:
- raise ValueError("This QPSK mod/demod works only for gray-coded constellations.")
+
+ pre_diff_code = True
+ if not differential:
+ constellation = digital_swig.constellation_qpsk()
+ if mod_code != mod_codes.GRAY_CODE:
+ raise ValueError("This QPSK mod/demod works only for gray-coded constellations.")
+ else:
+ constellation = digital_swig.constellation_dqpsk()
+ if mod_code not in (mod_codes.GRAY_CODE or mod_codes.NO_CODE):
+ raise ValueError("That mod_code is not supported for DQPSK mod/demod.")
+ if mod_code == mod_codes.NO_CODE:
+ pre_diff_code = False
+
super(qpsk_mod, self).__init__(constellation=constellation,
- gray_coded=gray_coded,
+ pre_diff_code=pre_diff_code,
*args, **kwargs)
@@ -81,7 +84,7 @@ class qpsk_mod(generic_mod):
class qpsk_demod(generic_demod):
- def __init__(self, constellation_points=_def_constellation_points,
+ def __init__(self, mod_code=_def_mod_code, differential=False,
*args, **kwargs):
"""
@@ -93,11 +96,20 @@ class qpsk_demod(generic_demod):
See generic_demod block for list of parameters.
"""
- constellation_points = _def_constellation_points
- constellation = digital_swig.constellation_qpsk()
- if constellation_points != 4:
- raise ValueError('Number of constellation points must be 4 for QPSK.')
+ pre_diff_code = True
+ if not differential:
+ constellation = digital_swig.constellation_qpsk()
+ if mod_code != mod_codes.GRAY_CODE:
+ raise ValueError("This QPSK mod/demod works only for gray-coded constellations.")
+ else:
+ constellation = digital_swig.constellation_dqpsk()
+ if mod_code not in (mod_codes.GRAY_CODE or mod_codes.NO_CODE):
+ raise ValueError("That mod_code is not supported for DQPSK mod/demod.")
+ if mod_code == mod_codes.NO_CODE:
+ pre_diff_code = False
+
super(qpsk_demod, self).__init__(constellation=constellation,
+ pre_diff_code=pre_diff_code,
*args, **kwargs)
@@ -106,20 +118,18 @@ class qpsk_demod(generic_demod):
# DQPSK constellation
# /////////////////////////////////////////////////////////////////////////////
-def dqpsk_constellation(m=_def_constellation_points):
- if m != _def_constellation_points:
- raise ValueError("DQPSK can only have 4 constellation points.")
+def dqpsk_constellation(mod_code=_def_mod_code):
+ if mod_code != mod_codes.GRAY_CODE:
+ raise ValueError("The DQPSK constellation is only generated for gray_coding. But it can be used for non-grayed coded modulation if one doesn't use the pre-differential code.")
return digital_swig.constellation_dqpsk()
# /////////////////////////////////////////////////////////////////////////////
# DQPSK modulator
# /////////////////////////////////////////////////////////////////////////////
-class dqpsk_mod(generic_mod):
+class dqpsk_mod(qpsk_mod):
- def __init__(self, constellation_points=_def_constellation_points,
- gray_coded=_def_gray_coded,
- differential=True, *args, **kwargs):
+ def __init__(self, mod_code=_def_mod_code, *args, **kwargs):
"""
Hierarchical block for RRC-filtered DQPSK modulation.
@@ -128,14 +138,7 @@ class dqpsk_mod(generic_mod):
See generic_mod block for list of parameters.
"""
-
- constellation_points = _def_constellation_points
- constellation = digital_swig.constellation_dqpsk()
- if constellation_points != 4:
- raise ValueError('Number of constellation points must be 4 for DQPSK.')
- super(dqpsk_mod, self).__init__(constellation=constellation,
- gray_coded=gray_coded,
- differential=True,
+ super(dqpsk_mod, self).__init__(mod_code, differential=True,
*args, **kwargs)
# /////////////////////////////////////////////////////////////////////////////
@@ -143,10 +146,9 @@ class dqpsk_mod(generic_mod):
#
# /////////////////////////////////////////////////////////////////////////////
-class dqpsk_demod(generic_demod):
+class dqpsk_demod(qpsk_demod):
- def __init__(self, constellation_points=_def_constellation_points,
- differential=True, *args, **kwargs):
+ def __init__(self, mod_code=_def_mod_code, *args, **kwargs):
"""
Hierarchical block for RRC-filtered DQPSK modulation.
@@ -156,12 +158,7 @@ class dqpsk_demod(generic_demod):
See generic_demod block for list of parameters.
"""
- constellation_points = _def_constellation_points
- constellation = digital_swig.constellation_dqpsk()
- if constellation_points != 4:
- raise ValueError('Number of constellation points must be 4 for DQPSK.')
- super(dqpsk_demod, self).__init__(constellation=constellation,
- differential=True,
+ super(dqpsk_demod, self).__init__(mod_code, differential=True,
*args, **kwargs)
#
diff --git a/gr-digital/swig/digital_ofdm_insert_preamble.i b/gr-digital/swig/digital_ofdm_insert_preamble.i
index 5f7b163698..0273c7fa75 100644
--- a/gr-digital/swig/digital_ofdm_insert_preamble.i
+++ b/gr-digital/swig/digital_ofdm_insert_preamble.i
@@ -32,4 +32,6 @@ class digital_ofdm_insert_preamble : public gr_block
protected:
digital_ofdm_insert_preamble(int fft_length,
const std::vector<std::vector<gr_complex> > &preamble);
+ public:
+ void enter_preamble();
};
diff --git a/gr-fcd/grc/fcd_source_c.xml b/gr-fcd/grc/fcd_source_c.xml
index 1b83cba7fb..f1726f88f2 100644
--- a/gr-fcd/grc/fcd_source_c.xml
+++ b/gr-fcd/grc/fcd_source_c.xml
@@ -12,7 +12,7 @@ self.$(id).set_lna_gain($lna)
#if $mixer() != +12.0
self.$(id).set_mixer_gain($mixer)
#end if
-#if $ppm() != 115
+#if $ppm() != -120
self.$(id).set_freq_corr($ppm)
#end if
#if ($dci() != 0.0) or ($dcq() != 0.0)
diff --git a/gr-fft/include/fft/fft.h b/gr-fft/include/fft/fft.h
index 5cc2e21e81..e3fd3f278a 100644
--- a/gr-fft/include/fft/fft.h
+++ b/gr-fft/include/fft/fft.h
@@ -37,15 +37,15 @@ namespace gr {
/*! \brief Helper function for allocating complex fft buffers
*/
- gr_complex* malloc_complex(int size);
+ FFT_API gr_complex* malloc_complex(int size);
/*! \brief Helper function for allocating float fft buffers
*/
- float* malloc_float(int size);
+ FFT_API float* malloc_float(int size);
/*! \brief Helper function for freeing fft buffers
*/
- void free(void *b);
+ FFT_API void free(void *b);
/*!
* \brief Export reference to planner mutex for those apps that
diff --git a/gr-fft/lib/CMakeLists.txt b/gr-fft/lib/CMakeLists.txt
index e2f17a1830..ea1248fbac 100644
--- a/gr-fft/lib/CMakeLists.txt
+++ b/gr-fft/lib/CMakeLists.txt
@@ -21,19 +21,16 @@
# Setup the include and linker paths
########################################################################
include_directories(
- ${GNURADIO_CORE_INCLUDE_DIRS}
- ${GR_FFT_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
+ ${GNURADIO_CORE_INCLUDE_DIRS}
+ ${GR_FFT_INCLUDE_DIRS}
+ ${Boost_INCLUDE_DIRS}
+ ${FFTW3F_INCLUDE_DIRS}
)
-include_directories(${FFT_INCLUDE_DIRS})
link_directories(${FFT_LIBRARY_DIRS})
-
-include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
-
-include_directories(${FFTW3F_INCLUDE_DIRS})
link_directories(${FFTW3F_LIBRARY_DIRS})
########################################################################
diff --git a/gr-fft/swig/CMakeLists.txt b/gr-fft/swig/CMakeLists.txt
index 63f5dfb0e2..7ea41f220e 100644
--- a/gr-fft/swig/CMakeLists.txt
+++ b/gr-fft/swig/CMakeLists.txt
@@ -30,7 +30,7 @@ set(GR_SWIG_INCLUDE_DIRS
)
set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/fft_swig_doc.i)
-set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../lib)
+set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../include/fft)
set(GR_SWIG_LIBRARIES gnuradio-fft)
diff --git a/gr-filter/CMakeLists.txt b/gr-filter/CMakeLists.txt
new file mode 100644
index 0000000000..b77a3d9d44
--- /dev/null
+++ b/gr-filter/CMakeLists.txt
@@ -0,0 +1,113 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+# Setup dependencies
+########################################################################
+include(GrBoost)
+
+########################################################################
+# Register component
+########################################################################
+include(GrComponent)
+
+GR_REGISTER_COMPONENT("gr-filter" ENABLE_GR_FILTER
+ ENABLE_GRUEL
+ ENABLE_VOLK
+ Boost_FOUND
+ ENABLE_GR_CORE
+ ENABLE_GR_FFT
+)
+
+GR_SET_GLOBAL(GR_FILTER_INCLUDE_DIRS
+ ${CMAKE_CURRENT_SOURCE_DIR}/lib
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
+ ${CMAKE_CURRENT_BINARY_DIR}/lib
+ ${CMAKE_CURRENT_BINARY_DIR}/include
+)
+
+SET(GR_PKG_FILTER_EXAMPLES_DIR ${GR_PKG_DATA_DIR}/examples/filter)
+
+########################################################################
+# Begin conditional configuration
+########################################################################
+if(ENABLE_GR_FILTER)
+
+########################################################################
+# Setup CPack components
+########################################################################
+include(GrPackage)
+CPACK_SET(CPACK_COMPONENT_GROUP_FILTER_DESCRIPTION "GNU Radio Filter Blocks")
+
+CPACK_COMPONENT("filter_runtime"
+ GROUP "Filter"
+ DISPLAY_NAME "Runtime"
+ DESCRIPTION "Runtime"
+ DEPENDS "core_runtime"
+)
+
+CPACK_COMPONENT("filter_devel"
+ GROUP "Filter"
+ DISPLAY_NAME "Development"
+ DESCRIPTION "C++ headers, package config, import libraries"
+ DEPENDS "core_devel"
+)
+
+CPACK_COMPONENT("filter_python"
+ GROUP "Filter"
+ DISPLAY_NAME "Python"
+ DESCRIPTION "Python modules for runtime; GRC xml files"
+ DEPENDS "core_python;filter_runtime"
+)
+
+CPACK_COMPONENT("filter_swig"
+ GROUP "Filter"
+ DISPLAY_NAME "SWIG"
+ DESCRIPTION "SWIG development .i files"
+ DEPENDS "core_swig;filter_python;filter_devel"
+)
+
+########################################################################
+# Add subdirectories
+########################################################################
+add_subdirectory(include/filter)
+add_subdirectory(lib)
+if(ENABLE_PYTHON)
+ add_subdirectory(swig)
+ add_subdirectory(python)
+ add_subdirectory(grc)
+endif(ENABLE_PYTHON)
+add_subdirectory(examples)
+add_subdirectory(doc)
+
+########################################################################
+# Create Pkg Config File
+########################################################################
+configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/gnuradio-filter.pc.in
+ ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-filter.pc
+@ONLY)
+
+install(
+ FILES ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-filter.pc
+ DESTINATION ${GR_LIBRARY_DIR}/pkgconfig
+ COMPONENT "filter_devel"
+)
+
+endif(ENABLE_GR_FILTER)
diff --git a/gr-filter/doc/CMakeLists.txt b/gr-filter/doc/CMakeLists.txt
new file mode 100644
index 0000000000..63447ed2ce
--- /dev/null
+++ b/gr-filter/doc/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+install(
+ FILES README.filter
+ DESTINATION ${GR_PKG_DOC_DIR}
+)
diff --git a/gr-filter/doc/README.filter b/gr-filter/doc/README.filter
new file mode 100644
index 0000000000..776acd46c7
--- /dev/null
+++ b/gr-filter/doc/README.filter
@@ -0,0 +1,13 @@
+This is the gr-filter package. It contains signal processing blocks to
+perform filtering operations.
+
+The Python namespace is in gnuradio.filter, which would be normally
+imported as:
+
+ from gnuradio import filter
+
+See the Doxygen documentation for details about the blocks available
+in this package. A quick listing of the details can be found in Python
+after importing by using:
+
+ help(filter)
diff --git a/gr-filter/doc/filter.dox b/gr-filter/doc/filter.dox
new file mode 100644
index 0000000000..fc3b52e91b
--- /dev/null
+++ b/gr-filter/doc/filter.dox
@@ -0,0 +1,27 @@
+/*! \page page_filter filter Signal Processing Blocks
+
+\section Introduction
+
+This is the gr-filter package. It contains signal processing blocks to
+perform filtering operations.
+
+The Python namespace is in gnuradio.filter, which would be normally
+imported as:
+
+\code
+ from gnuradio import filter
+\endcode
+
+See the Doxygen documentation for details about the blocks available
+in this package. A quick listing of the details can be found in Python
+after importing by using:
+
+\code
+ help(filter)
+\endcode
+
+\section Dependencies
+
+The filter blocks depend on \ref page_fft.
+
+*/
diff --git a/gr-filter/examples/CMakeLists.txt b/gr-filter/examples/CMakeLists.txt
new file mode 100644
index 0000000000..d94e5c16e1
--- /dev/null
+++ b/gr-filter/examples/CMakeLists.txt
@@ -0,0 +1,39 @@
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+include(GrPython)
+
+# Base stuff
+GR_PYTHON_INSTALL(PROGRAMS
+ channelize.py
+ chirp_channelize.py
+ decimate.py
+ fft_filter_ccc.py
+ fir_filter_ccc.py
+ fir_filter_fff.py
+ fmtest.py
+ interpolate.py
+ reconstruction.py
+ resampler.py
+ resampler_demo.grc
+ synth_filter.py
+ synth_to_chan.py
+ DESTINATION ${GR_PKG_FILTER_EXAMPLES_DIR}
+ COMPONENT "filter_python"
+)
diff --git a/gr-filter/examples/channelize.py b/gr-filter/examples/channelize.py
new file mode 100755
index 0000000000..1f784d9b06
--- /dev/null
+++ b/gr-filter/examples/channelize.py
@@ -0,0 +1,195 @@
+#!/usr/bin/env python
+#
+# Copyright 2009,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, blks2
+from gnuradio import filter
+import sys, time
+
+try:
+ import scipy
+ from scipy import fftpack
+except ImportError:
+ print "Error: Program requires scipy (see: www.scipy.org)."
+ sys.exit(1)
+
+try:
+ import pylab
+ from pylab import mlab
+except ImportError:
+ print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)."
+ sys.exit(1)
+
+class pfb_top_block(gr.top_block):
+ def __init__(self):
+ gr.top_block.__init__(self)
+
+ self._N = 2000000 # number of samples to use
+ self._fs = 1000 # initial sampling rate
+ self._M = M = 9 # Number of channels to channelize
+ self._ifs = M*self._fs # initial sampling rate
+
+ # Create a set of taps for the PFB channelizer
+ self._taps = filter.firdes.low_pass_2(1, self._ifs, 475.50, 50,
+ attenuation_dB=100,
+ window=filter.firdes.WIN_BLACKMAN_hARRIS)
+
+ # Calculate the number of taps per channel for our own information
+ tpc = scipy.ceil(float(len(self._taps)) / float(self._M))
+ print "Number of taps: ", len(self._taps)
+ print "Number of channels: ", self._M
+ print "Taps per channel: ", tpc
+
+ # Create a set of signals at different frequencies
+ # freqs lists the frequencies of the signals that get stored
+ # in the list "signals", which then get summed together
+ self.signals = list()
+ self.add = gr.add_cc()
+ freqs = [-70, -50, -30, -10, 10, 20, 40, 60, 80]
+ for i in xrange(len(freqs)):
+ f = freqs[i] + (M/2-M+i+1)*self._fs
+ self.signals.append(gr.sig_source_c(self._ifs, gr.GR_SIN_WAVE, f, 1))
+ self.connect(self.signals[i], (self.add,i))
+
+ self.head = gr.head(gr.sizeof_gr_complex, self._N)
+
+ # Construct the channelizer filter
+ self.pfb = filter.pfb.channelizer_ccf(self._M, self._taps, 1)
+
+ # Construct a vector sink for the input signal to the channelizer
+ self.snk_i = gr.vector_sink_c()
+
+ # Connect the blocks
+ self.connect(self.add, self.head, self.pfb)
+ self.connect(self.add, self.snk_i)
+
+ # Use this to play with the channel mapping
+ #self.pfb.set_channel_map([5,6,7,8,0,1,2,3,4])
+
+ # Create a vector sink for each of M output channels of the filter and connect it
+ self.snks = list()
+ for i in xrange(self._M):
+ self.snks.append(gr.vector_sink_c())
+ self.connect((self.pfb, i), self.snks[i])
+
+
+def main():
+ tstart = time.time()
+
+ tb = pfb_top_block()
+ tb.run()
+
+ tend = time.time()
+ print "Run time: %f" % (tend - tstart)
+
+ if 1:
+ fig_in = pylab.figure(1, figsize=(16,9), facecolor="w")
+ fig1 = pylab.figure(2, figsize=(16,9), facecolor="w")
+ fig2 = pylab.figure(3, figsize=(16,9), facecolor="w")
+
+ Ns = 1000
+ Ne = 10000
+
+ fftlen = 8192
+ winfunc = scipy.blackman
+ fs = tb._ifs
+
+ # Plot the input signal on its own figure
+ d = tb.snk_i.data()[Ns:Ne]
+ spin_f = fig_in.add_subplot(2, 1, 1)
+
+ X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
+ window = lambda d: d*winfunc(fftlen),
+ scale_by_freq=True)
+ X_in = 10.0*scipy.log10(abs(X))
+ f_in = scipy.arange(-fs/2.0, fs/2.0, fs/float(X_in.size))
+ pin_f = spin_f.plot(f_in, X_in, "b")
+ spin_f.set_xlim([min(f_in), max(f_in)+1])
+ spin_f.set_ylim([-200.0, 50.0])
+
+ spin_f.set_title("Input Signal", weight="bold")
+ spin_f.set_xlabel("Frequency (Hz)")
+ spin_f.set_ylabel("Power (dBW)")
+
+
+ Ts = 1.0/fs
+ Tmax = len(d)*Ts
+
+ t_in = scipy.arange(0, Tmax, Ts)
+ x_in = scipy.array(d)
+ spin_t = fig_in.add_subplot(2, 1, 2)
+ pin_t = spin_t.plot(t_in, x_in.real, "b")
+ pin_t = spin_t.plot(t_in, x_in.imag, "r")
+
+ spin_t.set_xlabel("Time (s)")
+ spin_t.set_ylabel("Amplitude")
+
+ Ncols = int(scipy.floor(scipy.sqrt(tb._M)))
+ Nrows = int(scipy.floor(tb._M / Ncols))
+ if(tb._M % Ncols != 0):
+ Nrows += 1
+
+ # Plot each of the channels outputs. Frequencies on Figure 2 and
+ # time signals on Figure 3
+ fs_o = tb._fs
+ Ts_o = 1.0/fs_o
+ Tmax_o = len(d)*Ts_o
+ for i in xrange(len(tb.snks)):
+ # remove issues with the transients at the beginning
+ # also remove some corruption at the end of the stream
+ # this is a bug, probably due to the corner cases
+ d = tb.snks[i].data()[Ns:Ne]
+
+ sp1_f = fig1.add_subplot(Nrows, Ncols, 1+i)
+ X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs_o,
+ window = lambda d: d*winfunc(fftlen),
+ scale_by_freq=True)
+ X_o = 10.0*scipy.log10(abs(X))
+ f_o = scipy.arange(-fs_o/2.0, fs_o/2.0, fs_o/float(X_o.size))
+ p2_f = sp1_f.plot(f_o, X_o, "b")
+ sp1_f.set_xlim([min(f_o), max(f_o)+1])
+ sp1_f.set_ylim([-200.0, 50.0])
+
+ sp1_f.set_title(("Channel %d" % i), weight="bold")
+ sp1_f.set_xlabel("Frequency (Hz)")
+ sp1_f.set_ylabel("Power (dBW)")
+
+ x_o = scipy.array(d)
+ t_o = scipy.arange(0, Tmax_o, Ts_o)
+ sp2_o = fig2.add_subplot(Nrows, Ncols, 1+i)
+ p2_o = sp2_o.plot(t_o, x_o.real, "b")
+ p2_o = sp2_o.plot(t_o, x_o.imag, "r")
+ sp2_o.set_xlim([min(t_o), max(t_o)+1])
+ sp2_o.set_ylim([-2, 2])
+
+ sp2_o.set_title(("Channel %d" % i), weight="bold")
+ sp2_o.set_xlabel("Time (s)")
+ sp2_o.set_ylabel("Amplitude")
+
+ pylab.show()
+
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
+
diff --git a/gr-filter/examples/chirp_channelize.py b/gr-filter/examples/chirp_channelize.py
new file mode 100755
index 0000000000..3638c55d1a
--- /dev/null
+++ b/gr-filter/examples/chirp_channelize.py
@@ -0,0 +1,205 @@
+#!/usr/bin/env python
+#
+# Copyright 2009,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, blks2
+from gnuradio import filter
+import sys, time
+
+try:
+ import scipy
+ from scipy import fftpack
+except ImportError:
+ print "Error: Program requires scipy (see: www.scipy.org)."
+ sys.exit(1)
+
+try:
+ import pylab
+ from pylab import mlab
+except ImportError:
+ print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)."
+ sys.exit(1)
+
+class pfb_top_block(gr.top_block):
+ def __init__(self):
+ gr.top_block.__init__(self)
+
+ self._N = 200000 # number of samples to use
+ self._fs = 9000 # initial sampling rate
+ self._M = 9 # Number of channels to channelize
+
+ # Create a set of taps for the PFB channelizer
+ self._taps = filter.firdes.low_pass_2(1, self._fs, 500, 20,
+ attenuation_dB=10,
+ window=filter.firdes.WIN_BLACKMAN_hARRIS)
+
+ # Calculate the number of taps per channel for our own information
+ tpc = scipy.ceil(float(len(self._taps)) / float(self._M))
+ print "Number of taps: ", len(self._taps)
+ print "Number of channels: ", self._M
+ print "Taps per channel: ", tpc
+
+ repeated = True
+ if(repeated):
+ self.vco_input = gr.sig_source_f(self._fs, gr.GR_SIN_WAVE, 0.25, 110)
+ else:
+ amp = 100
+ data = scipy.arange(0, amp, amp/float(self._N))
+ self.vco_input = gr.vector_source_f(data, False)
+
+ # Build a VCO controlled by either the sinusoid or single chirp tone
+ # Then convert this to a complex signal
+ self.vco = gr.vco_f(self._fs, 225, 1)
+ self.f2c = gr.float_to_complex()
+
+ self.head = gr.head(gr.sizeof_gr_complex, self._N)
+
+ # Construct the channelizer filter
+ self.pfb = filter.pfb.channelizer_ccf(self._M, self._taps)
+
+ # Construct a vector sink for the input signal to the channelizer
+ self.snk_i = gr.vector_sink_c()
+
+ # Connect the blocks
+ self.connect(self.vco_input, self.vco, self.f2c)
+ self.connect(self.f2c, self.head, self.pfb)
+ self.connect(self.f2c, self.snk_i)
+
+ # Create a vector sink for each of M output channels of the filter and connect it
+ self.snks = list()
+ for i in xrange(self._M):
+ self.snks.append(gr.vector_sink_c())
+ self.connect((self.pfb, i), self.snks[i])
+
+
+def main():
+ tstart = time.time()
+
+ tb = pfb_top_block()
+ tb.run()
+
+ tend = time.time()
+ print "Run time: %f" % (tend - tstart)
+
+ if 1:
+ fig_in = pylab.figure(1, figsize=(16,9), facecolor="w")
+ fig1 = pylab.figure(2, figsize=(16,9), facecolor="w")
+ fig2 = pylab.figure(3, figsize=(16,9), facecolor="w")
+ fig3 = pylab.figure(4, figsize=(16,9), facecolor="w")
+
+ Ns = 650
+ Ne = 20000
+
+ fftlen = 8192
+ winfunc = scipy.blackman
+ fs = tb._fs
+
+ # Plot the input signal on its own figure
+ d = tb.snk_i.data()[Ns:Ne]
+ spin_f = fig_in.add_subplot(2, 1, 1)
+
+ X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
+ window = lambda d: d*winfunc(fftlen),
+ scale_by_freq=True)
+ X_in = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+ f_in = scipy.arange(-fs/2.0, fs/2.0, fs/float(X_in.size))
+ pin_f = spin_f.plot(f_in, X_in, "b")
+ spin_f.set_xlim([min(f_in), max(f_in)+1])
+ spin_f.set_ylim([-200.0, 50.0])
+
+ spin_f.set_title("Input Signal", weight="bold")
+ spin_f.set_xlabel("Frequency (Hz)")
+ spin_f.set_ylabel("Power (dBW)")
+
+
+ Ts = 1.0/fs
+ Tmax = len(d)*Ts
+
+ t_in = scipy.arange(0, Tmax, Ts)
+ x_in = scipy.array(d)
+ spin_t = fig_in.add_subplot(2, 1, 2)
+ pin_t = spin_t.plot(t_in, x_in.real, "b")
+ pin_t = spin_t.plot(t_in, x_in.imag, "r")
+
+ spin_t.set_xlabel("Time (s)")
+ spin_t.set_ylabel("Amplitude")
+
+ Ncols = int(scipy.floor(scipy.sqrt(tb._M)))
+ Nrows = int(scipy.floor(tb._M / Ncols))
+ if(tb._M % Ncols != 0):
+ Nrows += 1
+
+ # Plot each of the channels outputs. Frequencies on Figure 2 and
+ # time signals on Figure 3
+ fs_o = tb._fs / tb._M
+ Ts_o = 1.0/fs_o
+ Tmax_o = len(d)*Ts_o
+ for i in xrange(len(tb.snks)):
+ # remove issues with the transients at the beginning
+ # also remove some corruption at the end of the stream
+ # this is a bug, probably due to the corner cases
+ d = tb.snks[i].data()[Ns:Ne]
+
+ sp1_f = fig1.add_subplot(Nrows, Ncols, 1+i)
+ X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs_o,
+ window = lambda d: d*winfunc(fftlen),
+ scale_by_freq=True)
+ X_o = 10.0*scipy.log10(abs(X))
+ f_o = freq
+ p2_f = sp1_f.plot(f_o, X_o, "b")
+ sp1_f.set_xlim([min(f_o), max(f_o)+1])
+ sp1_f.set_ylim([-200.0, 50.0])
+
+ sp1_f.set_title(("Channel %d" % i), weight="bold")
+ sp1_f.set_xlabel("Frequency (Hz)")
+ sp1_f.set_ylabel("Power (dBW)")
+
+ x_o = scipy.array(d)
+ t_o = scipy.arange(0, Tmax_o, Ts_o)
+ sp2_o = fig2.add_subplot(Nrows, Ncols, 1+i)
+ p2_o = sp2_o.plot(t_o, x_o.real, "b")
+ p2_o = sp2_o.plot(t_o, x_o.imag, "r")
+ sp2_o.set_xlim([min(t_o), max(t_o)+1])
+ sp2_o.set_ylim([-2, 2])
+
+ sp2_o.set_title(("Channel %d" % i), weight="bold")
+ sp2_o.set_xlabel("Time (s)")
+ sp2_o.set_ylabel("Amplitude")
+
+
+ sp3 = fig3.add_subplot(1,1,1)
+ p3 = sp3.plot(t_o, x_o.real)
+ sp3.set_xlim([min(t_o), max(t_o)+1])
+ sp3.set_ylim([-2, 2])
+
+ sp3.set_title("All Channels")
+ sp3.set_xlabel("Time (s)")
+ sp3.set_ylabel("Amplitude")
+
+ pylab.show()
+
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
+
diff --git a/gr-filter/examples/decimate.py b/gr-filter/examples/decimate.py
new file mode 100755
index 0000000000..7f1f03d8f2
--- /dev/null
+++ b/gr-filter/examples/decimate.py
@@ -0,0 +1,181 @@
+#!/usr/bin/env python
+#
+# Copyright 2009,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr
+from gnuradio import filter
+import sys, time
+
+try:
+ import scipy
+ from scipy import fftpack
+except ImportError:
+ print "Error: Program requires scipy (see: www.scipy.org)."
+ sys.exit(1)
+
+try:
+ import pylab
+ from pylab import mlab
+except ImportError:
+ print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)."
+ sys.exit(1)
+
+class pfb_top_block(gr.top_block):
+ def __init__(self):
+ gr.top_block.__init__(self)
+
+ self._N = 10000000 # number of samples to use
+ self._fs = 10000 # initial sampling rate
+ self._decim = 20 # Decimation rate
+
+ # Generate the prototype filter taps for the decimators with a 200 Hz bandwidth
+ self._taps = filter.firdes.low_pass_2(1, self._fs,
+ 200, 150,
+ attenuation_dB=120,
+ window=filter.firdes.WIN_BLACKMAN_hARRIS)
+
+ # Calculate the number of taps per channel for our own information
+ tpc = scipy.ceil(float(len(self._taps)) / float(self._decim))
+ print "Number of taps: ", len(self._taps)
+ print "Number of filters: ", self._decim
+ print "Taps per channel: ", tpc
+
+ # Build the input signal source
+ # We create a list of freqs, and a sine wave is generated and added to the source
+ # for each one of these frequencies.
+ self.signals = list()
+ self.add = gr.add_cc()
+ freqs = [10, 20, 2040]
+ for i in xrange(len(freqs)):
+ self.signals.append(gr.sig_source_c(self._fs, gr.GR_SIN_WAVE, freqs[i], 1))
+ self.connect(self.signals[i], (self.add,i))
+
+ self.head = gr.head(gr.sizeof_gr_complex, self._N)
+
+ # Construct a PFB decimator filter
+ self.pfb = filter.pfb.decimator_ccf(self._decim, self._taps, 0)
+
+ # Construct a standard FIR decimating filter
+ self.dec = filter.fir_filter_ccf(self._decim, self._taps)
+
+ self.snk_i = gr.vector_sink_c()
+
+ # Connect the blocks
+ self.connect(self.add, self.head, self.pfb)
+ self.connect(self.add, self.snk_i)
+
+ # Create the sink for the decimated siganl
+ self.snk = gr.vector_sink_c()
+ self.connect(self.pfb, self.snk)
+
+
+def main():
+ tb = pfb_top_block()
+
+ tstart = time.time()
+ tb.run()
+ tend = time.time()
+ print "Run time: %f" % (tend - tstart)
+
+ if 1:
+ fig1 = pylab.figure(1, figsize=(16,9))
+ fig2 = pylab.figure(2, figsize=(16,9))
+
+ Ns = 10000
+ Ne = 10000
+
+ fftlen = 8192
+ winfunc = scipy.blackman
+ fs = tb._fs
+
+ # Plot the input to the decimator
+
+ d = tb.snk_i.data()[Ns:Ns+Ne]
+ sp1_f = fig1.add_subplot(2, 1, 1)
+
+ X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
+ window = lambda d: d*winfunc(fftlen),
+ scale_by_freq=True)
+ X_in = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+ f_in = scipy.arange(-fs/2.0, fs/2.0, fs/float(X_in.size))
+ p1_f = sp1_f.plot(f_in, X_in, "b")
+ sp1_f.set_xlim([min(f_in), max(f_in)+1])
+ sp1_f.set_ylim([-200.0, 50.0])
+
+ sp1_f.set_title("Input Signal", weight="bold")
+ sp1_f.set_xlabel("Frequency (Hz)")
+ sp1_f.set_ylabel("Power (dBW)")
+
+ Ts = 1.0/fs
+ Tmax = len(d)*Ts
+
+ t_in = scipy.arange(0, Tmax, Ts)
+ x_in = scipy.array(d)
+ sp1_t = fig1.add_subplot(2, 1, 2)
+ p1_t = sp1_t.plot(t_in, x_in.real, "b")
+ p1_t = sp1_t.plot(t_in, x_in.imag, "r")
+ sp1_t.set_ylim([-tb._decim*1.1, tb._decim*1.1])
+
+ sp1_t.set_xlabel("Time (s)")
+ sp1_t.set_ylabel("Amplitude")
+
+
+ # Plot the output of the decimator
+ fs_o = tb._fs / tb._decim
+
+ sp2_f = fig2.add_subplot(2, 1, 1)
+ d = tb.snk.data()[Ns:Ns+Ne]
+ X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs_o,
+ window = lambda d: d*winfunc(fftlen),
+ scale_by_freq=True)
+ X_o = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+ f_o = scipy.arange(-fs_o/2.0, fs_o/2.0, fs_o/float(X_o.size))
+ p2_f = sp2_f.plot(f_o, X_o, "b")
+ sp2_f.set_xlim([min(f_o), max(f_o)+1])
+ sp2_f.set_ylim([-200.0, 50.0])
+
+ sp2_f.set_title("PFB Decimated Signal", weight="bold")
+ sp2_f.set_xlabel("Frequency (Hz)")
+ sp2_f.set_ylabel("Power (dBW)")
+
+
+ Ts_o = 1.0/fs_o
+ Tmax_o = len(d)*Ts_o
+
+ x_o = scipy.array(d)
+ t_o = scipy.arange(0, Tmax_o, Ts_o)
+ sp2_t = fig2.add_subplot(2, 1, 2)
+ p2_t = sp2_t.plot(t_o, x_o.real, "b-o")
+ p2_t = sp2_t.plot(t_o, x_o.imag, "r-o")
+ sp2_t.set_ylim([-2.5, 2.5])
+
+ sp2_t.set_xlabel("Time (s)")
+ sp2_t.set_ylabel("Amplitude")
+
+ pylab.show()
+
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
+
diff --git a/gr-filter/examples/fft_filter_ccc.py b/gr-filter/examples/fft_filter_ccc.py
new file mode 100755
index 0000000000..45e241a6f6
--- /dev/null
+++ b/gr-filter/examples/fft_filter_ccc.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, filter
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+try:
+ import scipy
+except ImportError:
+ print "Error: could not import scipy (http://www.scipy.org/)"
+ sys.exit(1)
+
+try:
+ import pylab
+except ImportError:
+ print "Error: could not import pylab (http://matplotlib.sourceforge.net/)"
+ sys.exit(1)
+
+class example_fft_filter_ccc(gr.top_block):
+ def __init__(self, N, fs, bw0, bw1, tw, atten, D):
+ gr.top_block.__init__(self)
+
+ self._nsamps = N
+ self._fs = fs
+ self._bw0 = bw0
+ self._bw1 = bw1
+ self._tw = tw
+ self._at = atten
+ self._decim = D
+ taps = filter.firdes.complex_band_pass_2(1, self._fs,
+ self._bw0, self._bw1,
+ self._tw, self._at)
+ print "Num. Taps: ", len(taps)
+
+ self.src = gr.noise_source_c(gr.GR_GAUSSIAN, 1)
+ self.head = gr.head(gr.sizeof_gr_complex, self._nsamps)
+
+ self.filt0 = filter.fft_filter_ccc(self._decim, taps)
+
+ self.vsnk_src = gr.vector_sink_c()
+ self.vsnk_out = gr.vector_sink_c()
+
+ self.connect(self.src, self.head, self.vsnk_src)
+ self.connect(self.head, self.filt0, self.vsnk_out)
+
+def main():
+ parser = OptionParser(option_class=eng_option, conflict_handler="resolve")
+ parser.add_option("-N", "--nsamples", type="int", default=10000,
+ help="Number of samples to process [default=%default]")
+ parser.add_option("-s", "--samplerate", type="eng_float", default=8000,
+ help="System sample rate [default=%default]")
+ parser.add_option("-S", "--start-pass", type="eng_float", default=1000,
+ help="Start of Passband [default=%default]")
+ parser.add_option("-E", "--end-pass", type="eng_float", default=2000,
+ help="End of Passband [default=%default]")
+ parser.add_option("-T", "--transition", type="eng_float", default=100,
+ help="Transition band [default=%default]")
+ parser.add_option("-A", "--attenuation", type="eng_float", default=80,
+ help="Stopband attenuation [default=%default]")
+ parser.add_option("-D", "--decimation", type="int", default=1,
+ help="Decmation factor [default=%default]")
+ (options, args) = parser.parse_args ()
+
+ put = example_fft_filter_ccc(options.nsamples,
+ options.samplerate,
+ options.start_pass,
+ options.end_pass,
+ options.transition,
+ options.attenuation,
+ options.decimation)
+ put.run()
+
+ data_src = scipy.array(put.vsnk_src.data())
+ data_snk = scipy.array(put.vsnk_out.data())
+
+ # Plot the signals PSDs
+ nfft = 1024
+ f1 = pylab.figure(1, figsize=(12,10))
+ s1 = f1.add_subplot(1,1,1)
+ s1.psd(data_src, NFFT=nfft, noverlap=nfft/4,
+ Fs=options.samplerate)
+ s1.psd(data_snk, NFFT=nfft, noverlap=nfft/4,
+ Fs=options.samplerate)
+
+ f2 = pylab.figure(2, figsize=(12,10))
+ s2 = f2.add_subplot(1,1,1)
+ s2.plot(data_src)
+ s2.plot(data_snk.real, 'g')
+
+ pylab.show()
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
+
diff --git a/gr-filter/examples/fir_filter_ccc.py b/gr-filter/examples/fir_filter_ccc.py
new file mode 100755
index 0000000000..baa05eeb7c
--- /dev/null
+++ b/gr-filter/examples/fir_filter_ccc.py
@@ -0,0 +1,92 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, filter
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+try:
+ import scipy
+except ImportError:
+ print "Error: could not import scipy (http://www.scipy.org/)"
+ sys.exit(1)
+
+try:
+ import pylab
+except ImportError:
+ print "Error: could not import pylab (http://matplotlib.sourceforge.net/)"
+ sys.exit(1)
+
+class example_fir_filter_ccc(gr.top_block):
+ def __init__(self, N, fs, bw, tw, atten, D):
+ gr.top_block.__init__(self)
+
+ self._nsamps = N
+ self._fs = fs
+ self._bw = bw
+ self._tw = tw
+ self._at = atten
+ self._decim = D
+ taps = filter.firdes.low_pass_2(1, self._fs, self._bw, self._tw, self._at)
+ print "Num. Taps: ", len(taps)
+
+ self.src = gr.noise_source_c(gr.GR_GAUSSIAN, 1)
+ self.head = gr.head(gr.sizeof_gr_complex, self._nsamps)
+
+ self.filt0 = filter.fir_filter_ccc(self._decim, taps)
+
+ self.vsnk_src = gr.vector_sink_c()
+ self.vsnk_out = gr.vector_sink_c()
+
+ self.connect(self.src, self.head, self.vsnk_src)
+ self.connect(self.head, self.filt0, self.vsnk_out)
+
+def main():
+ parser = OptionParser(option_class=eng_option, conflict_handler="resolve")
+ parser.add_option("-N", "--nsamples", type="int", default=10000,
+ help="Number of samples to process [default=%default]")
+ parser.add_option("-s", "--samplerate", type="eng_float", default=8000,
+ help="System sample rate [default=%default]")
+ parser.add_option("-B", "--bandwidth", type="eng_float", default=1000,
+ help="Filter bandwidth [default=%default]")
+ parser.add_option("-T", "--transition", type="eng_float", default=100,
+ help="Transition band [default=%default]")
+ parser.add_option("-A", "--attenuation", type="eng_float", default=80,
+ help="Stopband attenuation [default=%default]")
+ parser.add_option("-D", "--decimation", type="int", default=1,
+ help="Decmation factor [default=%default]")
+ (options, args) = parser.parse_args ()
+
+ put = example_fir_filter_ccc(options.nsamples,
+ options.samplerate,
+ options.bandwidth,
+ options.transition,
+ options.attenuation,
+ options.decimation)
+ put.run()
+
+ data_src = scipy.array(put.vsnk_src.data())
+ data_snk = scipy.array(put.vsnk_out.data())
+
+ # Plot the signals PSDs
+ nfft = 1024
+ f1 = pylab.figure(1, figsize=(12,10))
+ s1 = f1.add_subplot(1,1,1)
+ s1.psd(data_src, NFFT=nfft, noverlap=nfft/4,
+ Fs=options.samplerate)
+ s1.psd(data_snk, NFFT=nfft, noverlap=nfft/4,
+ Fs=options.samplerate)
+
+ f2 = pylab.figure(2, figsize=(12,10))
+ s2 = f2.add_subplot(1,1,1)
+ s2.plot(data_src)
+ s2.plot(data_snk.real, 'g')
+
+ pylab.show()
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
+
diff --git a/gr-filter/examples/fir_filter_fff.py b/gr-filter/examples/fir_filter_fff.py
new file mode 100755
index 0000000000..48769f00df
--- /dev/null
+++ b/gr-filter/examples/fir_filter_fff.py
@@ -0,0 +1,92 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, filter
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+try:
+ import scipy
+except ImportError:
+ print "Error: could not import scipy (http://www.scipy.org/)"
+ sys.exit(1)
+
+try:
+ import pylab
+except ImportError:
+ print "Error: could not import pylab (http://matplotlib.sourceforge.net/)"
+ sys.exit(1)
+
+class example_fir_filter_fff(gr.top_block):
+ def __init__(self, N, fs, bw, tw, atten, D):
+ gr.top_block.__init__(self)
+
+ self._nsamps = N
+ self._fs = fs
+ self._bw = bw
+ self._tw = tw
+ self._at = atten
+ self._decim = D
+ taps = filter.firdes.low_pass_2(1, self._fs, self._bw, self._tw, self._at)
+ print "Num. Taps: ", len(taps)
+
+ self.src = gr.noise_source_f(gr.GR_GAUSSIAN, 1)
+ self.head = gr.head(gr.sizeof_float, self._nsamps)
+
+ self.filt0 = filter.fir_filter_fff(self._decim, taps)
+
+ self.vsnk_src = gr.vector_sink_f()
+ self.vsnk_out = gr.vector_sink_f()
+
+ self.connect(self.src, self.head, self.vsnk_src)
+ self.connect(self.head, self.filt0, self.vsnk_out)
+
+def main():
+ parser = OptionParser(option_class=eng_option, conflict_handler="resolve")
+ parser.add_option("-N", "--nsamples", type="int", default=10000,
+ help="Number of samples to process [default=%default]")
+ parser.add_option("-s", "--samplerate", type="eng_float", default=8000,
+ help="System sample rate [default=%default]")
+ parser.add_option("-B", "--bandwidth", type="eng_float", default=1000,
+ help="Filter bandwidth [default=%default]")
+ parser.add_option("-T", "--transition", type="eng_float", default=100,
+ help="Transition band [default=%default]")
+ parser.add_option("-A", "--attenuation", type="eng_float", default=80,
+ help="Stopband attenuation [default=%default]")
+ parser.add_option("-D", "--decimation", type="int", default=1,
+ help="Decmation factor [default=%default]")
+ (options, args) = parser.parse_args ()
+
+ put = example_fir_filter_fff(options.nsamples,
+ options.samplerate,
+ options.bandwidth,
+ options.transition,
+ options.attenuation,
+ options.decimation)
+ put.run()
+
+ data_src = scipy.array(put.vsnk_src.data())
+ data_snk = scipy.array(put.vsnk_out.data())
+
+ # Plot the signals PSDs
+ nfft = 1024
+ f1 = pylab.figure(1, figsize=(12,10))
+ s1 = f1.add_subplot(1,1,1)
+ s1.psd(data_src, NFFT=nfft, noverlap=nfft/4,
+ Fs=options.samplerate)
+ s1.psd(data_snk, NFFT=nfft, noverlap=nfft/4,
+ Fs=options.samplerate)
+
+ f2 = pylab.figure(2, figsize=(12,10))
+ s2 = f2.add_subplot(1,1,1)
+ s2.plot(data_src)
+ s2.plot(data_snk.real, 'g')
+
+ pylab.show()
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
+
diff --git a/gr-filter/examples/fmtest.py b/gr-filter/examples/fmtest.py
new file mode 100755
index 0000000000..9b02526d9b
--- /dev/null
+++ b/gr-filter/examples/fmtest.py
@@ -0,0 +1,226 @@
+#!/usr/bin/env python
+#
+# Copyright 2009,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, blks2
+from gnuradio import filter
+import sys, math, time
+
+try:
+ import scipy
+ from scipy import fftpack
+except ImportError:
+ print "Error: Program requires scipy (see: www.scipy.org)."
+ sys.exit(1)
+
+try:
+ import pylab
+except ImportError:
+ print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)."
+ sys.exit(1)
+
+
+class fmtx(gr.hier_block2):
+ def __init__(self, lo_freq, audio_rate, if_rate):
+
+ gr.hier_block2.__init__(self, "build_fm",
+ gr.io_signature(1, 1, gr.sizeof_float),
+ gr.io_signature(1, 1, gr.sizeof_gr_complex))
+
+ fmtx = blks2.nbfm_tx (audio_rate, if_rate, max_dev=5e3, tau=75e-6)
+
+ # Local oscillator
+ lo = gr.sig_source_c (if_rate, # sample rate
+ gr.GR_SIN_WAVE, # waveform type
+ lo_freq, #frequency
+ 1.0, # amplitude
+ 0) # DC Offset
+ mixer = gr.multiply_cc ()
+
+ self.connect (self, fmtx, (mixer, 0))
+ self.connect (lo, (mixer, 1))
+ self.connect (mixer, self)
+
+class fmtest(gr.top_block):
+ def __init__(self):
+ gr.top_block.__init__(self)
+
+ self._nsamples = 1000000
+ self._audio_rate = 8000
+
+ # Set up N channels with their own baseband and IF frequencies
+ self._N = 5
+ chspacing = 16000
+ freq = [10, 20, 30, 40, 50]
+ f_lo = [0, 1*chspacing, -1*chspacing, 2*chspacing, -2*chspacing]
+
+ self._if_rate = 4*self._N*self._audio_rate
+
+ # Create a signal source and frequency modulate it
+ self.sum = gr.add_cc ()
+ for n in xrange(self._N):
+ sig = gr.sig_source_f(self._audio_rate, gr.GR_SIN_WAVE, freq[n], 0.5)
+ fm = fmtx(f_lo[n], self._audio_rate, self._if_rate)
+ self.connect(sig, fm)
+ self.connect(fm, (self.sum, n))
+
+ self.head = gr.head(gr.sizeof_gr_complex, self._nsamples)
+ self.snk_tx = gr.vector_sink_c()
+ self.channel = blks2.channel_model(0.1)
+
+ self.connect(self.sum, self.head, self.channel, self.snk_tx)
+
+
+ # Design the channlizer
+ self._M = 10
+ bw = chspacing/2.0
+ t_bw = chspacing/10.0
+ self._chan_rate = self._if_rate / self._M
+ self._taps = filter.firdes.low_pass_2(1, self._if_rate, bw, t_bw,
+ attenuation_dB=100,
+ window=filter.firdes.WIN_BLACKMAN_hARRIS)
+ tpc = math.ceil(float(len(self._taps)) / float(self._M))
+
+ print "Number of taps: ", len(self._taps)
+ print "Number of channels: ", self._M
+ print "Taps per channel: ", tpc
+
+ self.pfb = filter.pfb.channelizer_ccf(self._M, self._taps)
+
+ self.connect(self.channel, self.pfb)
+
+ # Create a file sink for each of M output channels of the filter and connect it
+ self.fmdet = list()
+ self.squelch = list()
+ self.snks = list()
+ for i in xrange(self._M):
+ self.fmdet.append(blks2.nbfm_rx(self._audio_rate, self._chan_rate))
+ self.squelch.append(blks2.standard_squelch(self._audio_rate*10))
+ self.snks.append(gr.vector_sink_f())
+ self.connect((self.pfb, i), self.fmdet[i], self.squelch[i], self.snks[i])
+
+ def num_tx_channels(self):
+ return self._N
+
+ def num_rx_channels(self):
+ return self._M
+
+def main():
+
+ fm = fmtest()
+
+ tstart = time.time()
+ fm.run()
+ tend = time.time()
+
+ if 1:
+ fig1 = pylab.figure(1, figsize=(12,10), facecolor="w")
+ fig2 = pylab.figure(2, figsize=(12,10), facecolor="w")
+ fig3 = pylab.figure(3, figsize=(12,10), facecolor="w")
+
+ Ns = 10000
+ Ne = 100000
+
+ fftlen = 8192
+ winfunc = scipy.blackman
+
+ # Plot transmitted signal
+ fs = fm._if_rate
+
+ d = fm.snk_tx.data()[Ns:Ns+Ne]
+ sp1_f = fig1.add_subplot(2, 1, 1)
+
+ X,freq = sp1_f.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
+ window = lambda d: d*winfunc(fftlen),
+ visible=False)
+ X_in = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+ f_in = scipy.arange(-fs/2.0, fs/2.0, fs/float(X_in.size))
+ p1_f = sp1_f.plot(f_in, X_in, "b")
+ sp1_f.set_xlim([min(f_in), max(f_in)+1])
+ sp1_f.set_ylim([-120.0, 20.0])
+
+ sp1_f.set_title("Input Signal", weight="bold")
+ sp1_f.set_xlabel("Frequency (Hz)")
+ sp1_f.set_ylabel("Power (dBW)")
+
+ Ts = 1.0/fs
+ Tmax = len(d)*Ts
+
+ t_in = scipy.arange(0, Tmax, Ts)
+ x_in = scipy.array(d)
+ sp1_t = fig1.add_subplot(2, 1, 2)
+ p1_t = sp1_t.plot(t_in, x_in.real, "b-o")
+ #p1_t = sp1_t.plot(t_in, x_in.imag, "r-o")
+ sp1_t.set_ylim([-5, 5])
+
+ # Set up the number of rows and columns for plotting the subfigures
+ Ncols = int(scipy.floor(scipy.sqrt(fm.num_rx_channels())))
+ Nrows = int(scipy.floor(fm.num_rx_channels() / Ncols))
+ if(fm.num_rx_channels() % Ncols != 0):
+ Nrows += 1
+
+ # Plot each of the channels outputs. Frequencies on Figure 2 and
+ # time signals on Figure 3
+ fs_o = fm._audio_rate
+ for i in xrange(len(fm.snks)):
+ # remove issues with the transients at the beginning
+ # also remove some corruption at the end of the stream
+ # this is a bug, probably due to the corner cases
+ d = fm.snks[i].data()[Ns:Ne]
+
+ sp2_f = fig2.add_subplot(Nrows, Ncols, 1+i)
+ X,freq = sp2_f.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs_o,
+ window = lambda d: d*winfunc(fftlen),
+ visible=False)
+ #X_o = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+ X_o = 10.0*scipy.log10(abs(X))
+ #f_o = scipy.arange(-fs_o/2.0, fs_o/2.0, fs_o/float(X_o.size))
+ f_o = scipy.arange(0, fs_o/2.0, fs_o/2.0/float(X_o.size))
+ p2_f = sp2_f.plot(f_o, X_o, "b")
+ sp2_f.set_xlim([min(f_o), max(f_o)+0.1])
+ sp2_f.set_ylim([-120.0, 20.0])
+ sp2_f.grid(True)
+
+ sp2_f.set_title(("Channel %d" % i), weight="bold")
+ sp2_f.set_xlabel("Frequency (kHz)")
+ sp2_f.set_ylabel("Power (dBW)")
+
+
+ Ts = 1.0/fs_o
+ Tmax = len(d)*Ts
+ t_o = scipy.arange(0, Tmax, Ts)
+
+ x_t = scipy.array(d)
+ sp2_t = fig3.add_subplot(Nrows, Ncols, 1+i)
+ p2_t = sp2_t.plot(t_o, x_t.real, "b")
+ p2_t = sp2_t.plot(t_o, x_t.imag, "r")
+ sp2_t.set_xlim([min(t_o), max(t_o)+1])
+ sp2_t.set_ylim([-1, 1])
+
+ sp2_t.set_xlabel("Time (s)")
+ sp2_t.set_ylabel("Amplitude")
+
+
+ pylab.show()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/gr-filter/examples/interpolate.py b/gr-filter/examples/interpolate.py
new file mode 100755
index 0000000000..56d78d597b
--- /dev/null
+++ b/gr-filter/examples/interpolate.py
@@ -0,0 +1,240 @@
+#!/usr/bin/env python
+#
+# Copyright 2009,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr
+from gnuradio import filter
+import sys, time
+
+try:
+ import scipy
+ from scipy import fftpack
+except ImportError:
+ print "Error: Program requires scipy (see: www.scipy.org)."
+ sys.exit(1)
+
+try:
+ import pylab
+ from pylab import mlab
+except ImportError:
+ print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)."
+ sys.exit(1)
+
+class pfb_top_block(gr.top_block):
+ def __init__(self):
+ gr.top_block.__init__(self)
+
+ self._N = 100000 # number of samples to use
+ self._fs = 2000 # initial sampling rate
+ self._interp = 5 # Interpolation rate for PFB interpolator
+ self._ainterp = 5.5 # Resampling rate for the PFB arbitrary resampler
+
+ # Frequencies of the signals we construct
+ freq1 = 100
+ freq2 = 200
+
+ # Create a set of taps for the PFB interpolator
+ # This is based on the post-interpolation sample rate
+ self._taps = filter.firdes.low_pass_2(self._interp,
+ self._interp*self._fs,
+ freq2+50, 50,
+ attenuation_dB=120,
+ window=filter.firdes.WIN_BLACKMAN_hARRIS)
+
+ # Create a set of taps for the PFB arbitrary resampler
+ # The filter size is the number of filters in the filterbank; 32 will give very low side-lobes,
+ # and larger numbers will reduce these even farther
+ # The taps in this filter are based on a sampling rate of the filter size since it acts
+ # internally as an interpolator.
+ flt_size = 32
+ self._taps2 = filter.firdes.low_pass_2(flt_size,
+ flt_size*self._fs,
+ freq2+50, 150,
+ attenuation_dB=120,
+ window=filter.firdes.WIN_BLACKMAN_hARRIS)
+
+ # Calculate the number of taps per channel for our own information
+ tpc = scipy.ceil(float(len(self._taps)) / float(self._interp))
+ print "Number of taps: ", len(self._taps)
+ print "Number of filters: ", self._interp
+ print "Taps per channel: ", tpc
+
+ # Create a couple of signals at different frequencies
+ self.signal1 = gr.sig_source_c(self._fs, gr.GR_SIN_WAVE, freq1, 0.5)
+ self.signal2 = gr.sig_source_c(self._fs, gr.GR_SIN_WAVE, freq2, 0.5)
+ self.signal = gr.add_cc()
+
+ self.head = gr.head(gr.sizeof_gr_complex, self._N)
+
+ # Construct the PFB interpolator filter
+ self.pfb = filter.pfb.interpolator_ccf(self._interp, self._taps)
+
+ # Construct the PFB arbitrary resampler filter
+ self.pfb_ar = filter.pfb.arb_resampler_ccf(self._ainterp, self._taps2, flt_size)
+ self.snk_i = gr.vector_sink_c()
+
+ #self.pfb_ar.pfb.print_taps()
+ #self.pfb.pfb.print_taps()
+
+ # Connect the blocks
+ self.connect(self.signal1, self.head, (self.signal,0))
+ self.connect(self.signal2, (self.signal,1))
+ self.connect(self.signal, self.pfb)
+ self.connect(self.signal, self.pfb_ar)
+ self.connect(self.signal, self.snk_i)
+
+ # Create the sink for the interpolated signals
+ self.snk1 = gr.vector_sink_c()
+ self.snk2 = gr.vector_sink_c()
+ self.connect(self.pfb, self.snk1)
+ self.connect(self.pfb_ar, self.snk2)
+
+
+def main():
+ tb = pfb_top_block()
+
+ tstart = time.time()
+ tb.run()
+ tend = time.time()
+ print "Run time: %f" % (tend - tstart)
+
+
+ if 1:
+ fig1 = pylab.figure(1, figsize=(12,10), facecolor="w")
+ fig2 = pylab.figure(2, figsize=(12,10), facecolor="w")
+ fig3 = pylab.figure(3, figsize=(12,10), facecolor="w")
+
+ Ns = 10000
+ Ne = 10000
+
+ fftlen = 8192
+ winfunc = scipy.blackman
+
+ # Plot input signal
+ fs = tb._fs
+
+ d = tb.snk_i.data()[Ns:Ns+Ne]
+ sp1_f = fig1.add_subplot(2, 1, 1)
+
+ X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
+ window = lambda d: d*winfunc(fftlen),
+ scale_by_freq=True)
+ X_in = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+ f_in = scipy.arange(-fs/2.0, fs/2.0, fs/float(X_in.size))
+ p1_f = sp1_f.plot(f_in, X_in, "b")
+ sp1_f.set_xlim([min(f_in), max(f_in)+1])
+ sp1_f.set_ylim([-200.0, 50.0])
+
+
+ sp1_f.set_title("Input Signal", weight="bold")
+ sp1_f.set_xlabel("Frequency (Hz)")
+ sp1_f.set_ylabel("Power (dBW)")
+
+ Ts = 1.0/fs
+ Tmax = len(d)*Ts
+
+ t_in = scipy.arange(0, Tmax, Ts)
+ x_in = scipy.array(d)
+ sp1_t = fig1.add_subplot(2, 1, 2)
+ p1_t = sp1_t.plot(t_in, x_in.real, "b-o")
+ #p1_t = sp1_t.plot(t_in, x_in.imag, "r-o")
+ sp1_t.set_ylim([-2.5, 2.5])
+
+ sp1_t.set_title("Input Signal", weight="bold")
+ sp1_t.set_xlabel("Time (s)")
+ sp1_t.set_ylabel("Amplitude")
+
+
+ # Plot output of PFB interpolator
+ fs_int = tb._fs*tb._interp
+
+ sp2_f = fig2.add_subplot(2, 1, 1)
+ d = tb.snk1.data()[Ns:Ns+(tb._interp*Ne)]
+ X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
+ window = lambda d: d*winfunc(fftlen),
+ scale_by_freq=True)
+ X_o = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+ f_o = scipy.arange(-fs_int/2.0, fs_int/2.0, fs_int/float(X_o.size))
+ p2_f = sp2_f.plot(f_o, X_o, "b")
+ sp2_f.set_xlim([min(f_o), max(f_o)+1])
+ sp2_f.set_ylim([-200.0, 50.0])
+
+ sp2_f.set_title("Output Signal from PFB Interpolator", weight="bold")
+ sp2_f.set_xlabel("Frequency (Hz)")
+ sp2_f.set_ylabel("Power (dBW)")
+
+ Ts_int = 1.0/fs_int
+ Tmax = len(d)*Ts_int
+
+ t_o = scipy.arange(0, Tmax, Ts_int)
+ x_o1 = scipy.array(d)
+ sp2_t = fig2.add_subplot(2, 1, 2)
+ p2_t = sp2_t.plot(t_o, x_o1.real, "b-o")
+ #p2_t = sp2_t.plot(t_o, x_o.imag, "r-o")
+ sp2_t.set_ylim([-2.5, 2.5])
+
+ sp2_t.set_title("Output Signal from PFB Interpolator", weight="bold")
+ sp2_t.set_xlabel("Time (s)")
+ sp2_t.set_ylabel("Amplitude")
+
+
+ # Plot output of PFB arbitrary resampler
+ fs_aint = tb._fs * tb._ainterp
+
+ sp3_f = fig3.add_subplot(2, 1, 1)
+ d = tb.snk2.data()[Ns:Ns+(tb._interp*Ne)]
+ X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
+ window = lambda d: d*winfunc(fftlen),
+ scale_by_freq=True)
+ X_o = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+ f_o = scipy.arange(-fs_aint/2.0, fs_aint/2.0, fs_aint/float(X_o.size))
+ p3_f = sp3_f.plot(f_o, X_o, "b")
+ sp3_f.set_xlim([min(f_o), max(f_o)+1])
+ sp3_f.set_ylim([-200.0, 50.0])
+
+ sp3_f.set_title("Output Signal from PFB Arbitrary Resampler", weight="bold")
+ sp3_f.set_xlabel("Frequency (Hz)")
+ sp3_f.set_ylabel("Power (dBW)")
+
+ Ts_aint = 1.0/fs_aint
+ Tmax = len(d)*Ts_aint
+
+ t_o = scipy.arange(0, Tmax, Ts_aint)
+ x_o2 = scipy.array(d)
+ sp3_f = fig3.add_subplot(2, 1, 2)
+ p3_f = sp3_f.plot(t_o, x_o2.real, "b-o")
+ p3_f = sp3_f.plot(t_o, x_o1.real, "m-o")
+ #p3_f = sp3_f.plot(t_o, x_o2.imag, "r-o")
+ sp3_f.set_ylim([-2.5, 2.5])
+
+ sp3_f.set_title("Output Signal from PFB Arbitrary Resampler", weight="bold")
+ sp3_f.set_xlabel("Time (s)")
+ sp3_f.set_ylabel("Amplitude")
+
+ pylab.show()
+
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
+
diff --git a/gr-filter/examples/reconstruction.py b/gr-filter/examples/reconstruction.py
new file mode 100755
index 0000000000..9e38f3669c
--- /dev/null
+++ b/gr-filter/examples/reconstruction.py
@@ -0,0 +1,164 @@
+#!/usr/bin/env python
+#
+# Copyright 2010,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, digital
+from gnuradio import filter
+
+try:
+ import scipy
+ from scipy import fftpack
+except ImportError:
+ print "Error: Program requires scipy (see: www.scipy.org)."
+ sys.exit(1)
+
+try:
+ import pylab
+except ImportError:
+ print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)."
+ sys.exit(1)
+
+fftlen = 8192
+
+def main():
+ N = 10000
+ fs = 2000.0
+ Ts = 1.0/fs
+ t = scipy.arange(0, N*Ts, Ts)
+
+ # When playing with the number of channels, be careful about the filter
+ # specs and the channel map of the synthesizer set below.
+ nchans = 10
+
+ # Build the filter(s)
+ bw = 1000
+ tb = 400
+ proto_taps = filter.firdes.low_pass_2(1, nchans*fs,
+ bw, tb, 80,
+ filter.firdes.WIN_BLACKMAN_hARRIS)
+ print "Filter length: ", len(proto_taps)
+
+
+ # Create a modulated signal
+ npwr = 0.01
+ data = scipy.random.randint(0, 256, N)
+ rrc_taps = filter.firdes.root_raised_cosine(1, 2, 1, 0.35, 41)
+
+ src = gr.vector_source_b(data.astype(scipy.uint8).tolist(), False)
+ mod = digital.bpsk_mod(samples_per_symbol=2)
+ chan = gr.channel_model(npwr)
+ rrc = filter.fft_filter_ccc(1, rrc_taps)
+
+ # Split it up into pieces
+ channelizer = filter.pfb.channelizer_ccf(nchans, proto_taps, 2)
+
+ # Put the pieces back together again
+ syn_taps = [nchans*t for t in proto_taps]
+ synthesizer = filter.pfb_synthesizer_ccf(nchans, syn_taps, True)
+ src_snk = gr.vector_sink_c()
+ snk = gr.vector_sink_c()
+
+ # Remap the location of the channels
+ # Can be done in synth or channelizer (watch out for rotattions in
+ # the channelizer)
+ synthesizer.set_channel_map([ 0, 1, 2, 3, 4,
+ 15, 16, 17, 18, 19])
+
+ tb = gr.top_block()
+ tb.connect(src, mod, chan, rrc, channelizer)
+ tb.connect(rrc, src_snk)
+
+ vsnk = []
+ for i in xrange(nchans):
+ tb.connect((channelizer,i), (synthesizer, i))
+
+ vsnk.append(gr.vector_sink_c())
+ tb.connect((channelizer,i), vsnk[i])
+
+ tb.connect(synthesizer, snk)
+ tb.run()
+
+ sin = scipy.array(src_snk.data()[1000:])
+ sout = scipy.array(snk.data()[1000:])
+
+
+ # Plot original signal
+ fs_in = nchans*fs
+ f1 = pylab.figure(1, figsize=(16,12), facecolor='w')
+ s11 = f1.add_subplot(2,2,1)
+ s11.psd(sin, NFFT=fftlen, Fs=fs_in)
+ s11.set_title("PSD of Original Signal")
+ s11.set_ylim([-200, -20])
+
+ s12 = f1.add_subplot(2,2,2)
+ s12.plot(sin.real[1000:1500], "o-b")
+ s12.plot(sin.imag[1000:1500], "o-r")
+ s12.set_title("Original Signal in Time")
+
+ start = 1
+ skip = 4
+ s13 = f1.add_subplot(2,2,3)
+ s13.plot(sin.real[start::skip], sin.imag[start::skip], "o")
+ s13.set_title("Constellation")
+ s13.set_xlim([-2, 2])
+ s13.set_ylim([-2, 2])
+
+ # Plot channels
+ nrows = int(scipy.sqrt(nchans))
+ ncols = int(scipy.ceil(float(nchans)/float(nrows)))
+
+ f2 = pylab.figure(2, figsize=(16,12), facecolor='w')
+ for n in xrange(nchans):
+ s = f2.add_subplot(nrows, ncols, n+1)
+ s.psd(vsnk[n].data(), NFFT=fftlen, Fs=fs_in)
+ s.set_title("Channel {0}".format(n))
+ s.set_ylim([-200, -20])
+
+ # Plot reconstructed signal
+ fs_out = 2*nchans*fs
+ f3 = pylab.figure(3, figsize=(16,12), facecolor='w')
+ s31 = f3.add_subplot(2,2,1)
+ s31.psd(sout, NFFT=fftlen, Fs=fs_out)
+ s31.set_title("PSD of Reconstructed Signal")
+ s31.set_ylim([-200, -20])
+
+ s32 = f3.add_subplot(2,2,2)
+ s32.plot(sout.real[1000:1500], "o-b")
+ s32.plot(sout.imag[1000:1500], "o-r")
+ s32.set_title("Reconstructed Signal in Time")
+
+ start = 2
+ skip = 4
+ s33 = f3.add_subplot(2,2,3)
+ s33.plot(sout.real[start::skip], sout.imag[start::skip], "o")
+ s33.set_title("Constellation")
+ s33.set_xlim([-2, 2])
+ s33.set_ylim([-2, 2])
+
+ pylab.show()
+
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
+
diff --git a/gr-filter/examples/resampler.py b/gr-filter/examples/resampler.py
new file mode 100755
index 0000000000..395e095cbd
--- /dev/null
+++ b/gr-filter/examples/resampler.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python
+#
+# Copyright 2009,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr
+from gnuradio import filter
+import sys
+
+try:
+ import scipy
+except ImportError:
+ print "Error: Program requires scipy (see: www.scipy.org)."
+ sys.exit(1)
+
+try:
+ import pylab
+except ImportError:
+ print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)."
+ sys.exit(1)
+
+class mytb(gr.top_block):
+ def __init__(self, fs_in, fs_out, fc, N=10000):
+ gr.top_block.__init__(self)
+
+ rerate = float(fs_out) / float(fs_in)
+ print "Resampling from %f to %f by %f " %(fs_in, fs_out, rerate)
+
+ # Creating our own taps
+ taps = gr.firdes.low_pass_2(32, 32, 0.25, 0.1, 80)
+
+ self.src = gr.sig_source_c(fs_in, gr.GR_SIN_WAVE, fc, 1)
+ #self.src = gr.noise_source_c(gr.GR_GAUSSIAN, 1)
+ self.head = gr.head(gr.sizeof_gr_complex, N)
+
+ # A resampler with our taps
+ self.resamp_0 = filter.pfb.arb_resampler_ccf(rerate, taps,
+ flt_size=32)
+
+ # A resampler that just needs a resampling rate.
+ # Filter is created for us and designed to cover
+ # entire bandwidth of the input signal.
+ # An optional atten=XX rate can be used here to
+ # specify the out-of-band rejection (default=80).
+ self.resamp_1 = filter.pfb.arb_resampler_ccf(rerate)
+
+ self.snk_in = gr.vector_sink_c()
+ self.snk_0 = gr.vector_sink_c()
+ self.snk_1 = gr.vector_sink_c()
+
+ self.connect(self.src, self.head, self.snk_in)
+ self.connect(self.head, self.resamp_0, self.snk_0)
+ self.connect(self.head, self.resamp_1, self.snk_1)
+
+def main():
+ fs_in = 8000
+ fs_out = 20000
+ fc = 1000
+ N = 10000
+
+ tb = mytb(fs_in, fs_out, fc, N)
+ tb.run()
+
+
+ # Plot PSD of signals
+ nfftsize = 2048
+ fig1 = pylab.figure(1, figsize=(10,10), facecolor="w")
+ sp1 = fig1.add_subplot(2,1,1)
+ sp1.psd(tb.snk_in.data(), NFFT=nfftsize,
+ noverlap=nfftsize/4, Fs = fs_in)
+ sp1.set_title(("Input Signal at f_s=%.2f kHz" % (fs_in/1000.0)))
+ sp1.set_xlim([-fs_in/2, fs_in/2])
+
+ sp2 = fig1.add_subplot(2,1,2)
+ sp2.psd(tb.snk_0.data(), NFFT=nfftsize,
+ noverlap=nfftsize/4, Fs = fs_out,
+ label="With our filter")
+ sp2.psd(tb.snk_1.data(), NFFT=nfftsize,
+ noverlap=nfftsize/4, Fs = fs_out,
+ label="With auto-generated filter")
+ sp2.set_title(("Output Signals at f_s=%.2f kHz" % (fs_out/1000.0)))
+ sp2.set_xlim([-fs_out/2, fs_out/2])
+ sp2.legend()
+
+ # Plot signals in time
+ Ts_in = 1.0/fs_in
+ Ts_out = 1.0/fs_out
+ t_in = scipy.arange(0, len(tb.snk_in.data())*Ts_in, Ts_in)
+ t_out = scipy.arange(0, len(tb.snk_0.data())*Ts_out, Ts_out)
+
+ fig2 = pylab.figure(2, figsize=(10,10), facecolor="w")
+ sp21 = fig2.add_subplot(2,1,1)
+ sp21.plot(t_in, tb.snk_in.data())
+ sp21.set_title(("Input Signal at f_s=%.2f kHz" % (fs_in/1000.0)))
+ sp21.set_xlim([t_in[100], t_in[200]])
+
+ sp22 = fig2.add_subplot(2,1,2)
+ sp22.plot(t_out, tb.snk_0.data(),
+ label="With our filter")
+ sp22.plot(t_out, tb.snk_1.data(),
+ label="With auto-generated filter")
+ sp22.set_title(("Output Signals at f_s=%.2f kHz" % (fs_out/1000.0)))
+ r = float(fs_out)/float(fs_in)
+ sp22.set_xlim([t_out[r * 100], t_out[r * 200]])
+ sp22.legend()
+
+ pylab.show()
+
+if __name__ == "__main__":
+ main()
+
diff --git a/gr-filter/examples/resampler_demo.grc b/gr-filter/examples/resampler_demo.grc
new file mode 100644
index 0000000000..b3991ac198
--- /dev/null
+++ b/gr-filter/examples/resampler_demo.grc
@@ -0,0 +1,630 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+ <timestamp>Tue Jun 19 21:31:30 2012</timestamp>
+ <block>
+ <key>options</key>
+ <param>
+ <key>id</key>
+ <value>resampler_demo</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value></value>
+ </param>
+ <param>
+ <key>author</key>
+ <value></value>
+ </param>
+ <param>
+ <key>description</key>
+ <value></value>
+ </param>
+ <param>
+ <key>window_size</key>
+ <value>1280, 1024</value>
+ </param>
+ <param>
+ <key>generate_options</key>
+ <value>wx_gui</value>
+ </param>
+ <param>
+ <key>category</key>
+ <value>Custom</value>
+ </param>
+ <param>
+ <key>run_options</key>
+ <value>prompt</value>
+ </param>
+ <param>
+ <key>run</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>realtime_scheduling</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(10, 10)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>import</key>
+ <param>
+ <key>id</key>
+ <value>import_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>import</key>
+ <value>import math</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(11, 59)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>rs_taps</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>firdes.low_pass(nphases, nphases, frac_bw, 0.5-frac_bw)</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(273, 154)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_add_const_vxx</key>
+ <param>
+ <key>id</key>
+ <value>adder</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>const</key>
+ <value>-1.0</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(227, 303)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_throttle</key>
+ <param>
+ <key>id</key>
+ <value>throttle</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>samples_per_second</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(227, 493)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>wxgui_fftsink2</key>
+ <param>
+ <key>id</key>
+ <value>orig_fft</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value>Original Spectrum</value>
+ </param>
+ <param>
+ <key>samp_rate</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>baseband_freq</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>y_per_div</key>
+ <value>10</value>
+ </param>
+ <param>
+ <key>y_divs</key>
+ <value>10</value>
+ </param>
+ <param>
+ <key>ref_level</key>
+ <value>30</value>
+ </param>
+ <param>
+ <key>ref_scale</key>
+ <value>2.0</value>
+ </param>
+ <param>
+ <key>fft_size</key>
+ <value>1024</value>
+ </param>
+ <param>
+ <key>fft_rate</key>
+ <value>30</value>
+ </param>
+ <param>
+ <key>peak_hold</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>average</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>avg_alpha</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>win</key>
+ <value>None</value>
+ </param>
+ <param>
+ <key>win_size</key>
+ <value></value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value>1, 0, 1, 3</value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(409, 289)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>180</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_sig_source_x</key>
+ <param>
+ <key>id</key>
+ <value>tri_source</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>samp_rate</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>waveform</key>
+ <value>gr.GR_TRI_WAVE</value>
+ </param>
+ <param>
+ <key>freq</key>
+ <value>0.05</value>
+ </param>
+ <param>
+ <key>amp</key>
+ <value>2.0</value>
+ </param>
+ <param>
+ <key>offset</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(21, 271)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>nphases</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>32</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(185, 153)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable_static_text</key>
+ <param>
+ <key>id</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>Sample Rate</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>44100</value>
+ </param>
+ <param>
+ <key>converver</key>
+ <value>float_converter</value>
+ </param>
+ <param>
+ <key>formatter</key>
+ <value>None</value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value>0, 0, 1, 1</value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(179, 14)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable_static_text</key>
+ <param>
+ <key>id</key>
+ <value>new_rate</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>Resampled Rate</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>48000</value>
+ </param>
+ <param>
+ <key>converver</key>
+ <value>float_converter</value>
+ </param>
+ <param>
+ <key>formatter</key>
+ <value>None</value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value>0, 1, 1, 1</value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(328, 15)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable_static_text</key>
+ <param>
+ <key>id</key>
+ <value>frac_bw</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>Fractional Bandwidth</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>0.45</value>
+ </param>
+ <param>
+ <key>converver</key>
+ <value>float_converter</value>
+ </param>
+ <param>
+ <key>formatter</key>
+ <value>lambda x: "%0.2f"%x</value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value>0,2,1,1</value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(473, 14)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_frequency_modulator_fc</key>
+ <param>
+ <key>id</key>
+ <value>fm_mod</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>sensitivity</key>
+ <value>math.pi</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(411, 493)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>wxgui_fftsink2</key>
+ <param>
+ <key>id</key>
+ <value>resamp_fft</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value>Resampled Spectrum</value>
+ </param>
+ <param>
+ <key>samp_rate</key>
+ <value>new_rate</value>
+ </param>
+ <param>
+ <key>baseband_freq</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>y_per_div</key>
+ <value>10</value>
+ </param>
+ <param>
+ <key>y_divs</key>
+ <value>10</value>
+ </param>
+ <param>
+ <key>ref_level</key>
+ <value>30</value>
+ </param>
+ <param>
+ <key>ref_scale</key>
+ <value>2.0</value>
+ </param>
+ <param>
+ <key>fft_size</key>
+ <value>1024</value>
+ </param>
+ <param>
+ <key>fft_rate</key>
+ <value>30</value>
+ </param>
+ <param>
+ <key>peak_hold</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>average</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>avg_alpha</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>win</key>
+ <value>None</value>
+ </param>
+ <param>
+ <key>win_size</key>
+ <value></value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value>2, 0, 1, 3</value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(640, 256)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>180</value>
+ </param>
+ </block>
+ <block>
+ <key>pfb_arb_resampler_xxx</key>
+ <param>
+ <key>id</key>
+ <value>pfb_arb_resampler_xxx_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>ccf</value>
+ </param>
+ <param>
+ <key>rrate</key>
+ <value>float(new_rate)/samp_rate</value>
+ </param>
+ <param>
+ <key>taps</key>
+ <value>rs_taps</value>
+ </param>
+ <param>
+ <key>nfilts</key>
+ <value>nphases</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(649, 469)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <connection>
+ <source_block_id>tri_source</source_block_id>
+ <sink_block_id>adder</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>adder</source_block_id>
+ <sink_block_id>throttle</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>fm_mod</source_block_id>
+ <sink_block_id>orig_fft</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>throttle</source_block_id>
+ <sink_block_id>fm_mod</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>fm_mod</source_block_id>
+ <sink_block_id>pfb_arb_resampler_xxx_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>pfb_arb_resampler_xxx_0</source_block_id>
+ <sink_block_id>resamp_fft</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+</flow_graph>
diff --git a/gr-filter/examples/synth_filter.py b/gr-filter/examples/synth_filter.py
new file mode 100755
index 0000000000..a5b6fdf4cb
--- /dev/null
+++ b/gr-filter/examples/synth_filter.py
@@ -0,0 +1,85 @@
+#!/usr/bin/env python
+#
+# Copyright 2010,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr
+from gnuradio import filter
+import sys
+
+try:
+ import scipy
+except ImportError:
+ print "Error: Program requires scipy (see: www.scipy.org)."
+ sys.exit(1)
+
+try:
+ import pylab
+except ImportError:
+ print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)."
+ sys.exit(1)
+
+def main():
+ N = 1000000
+ fs = 8000
+
+ freqs = [100, 200, 300, 400, 500]
+ nchans = 7
+
+ sigs = list()
+ for fi in freqs:
+ s = gr.sig_source_c(fs, gr.GR_SIN_WAVE, fi, 1)
+ sigs.append(s)
+
+ taps = filter.firdes.low_pass_2(len(freqs), fs,
+ fs/float(nchans)/2, 100, 100)
+ print "Num. Taps = %d (taps per filter = %d)" % (len(taps),
+ len(taps)/nchans)
+ filtbank = filter.pfb_synthesizer_ccf(nchans, taps)
+
+ head = gr.head(gr.sizeof_gr_complex, N)
+ snk = gr.vector_sink_c()
+
+ tb = gr.top_block()
+ tb.connect(filtbank, head, snk)
+
+ for i,si in enumerate(sigs):
+ tb.connect(si, (filtbank, i))
+
+ tb.run()
+
+ if 1:
+ f1 = pylab.figure(1)
+ s1 = f1.add_subplot(1,1,1)
+ s1.plot(snk.data()[1000:])
+
+ fftlen = 2048
+ f2 = pylab.figure(2)
+ s2 = f2.add_subplot(1,1,1)
+ winfunc = scipy.blackman
+ s2.psd(snk.data()[10000:], NFFT=fftlen,
+ Fs = nchans*fs,
+ noverlap=fftlen/4,
+ window = lambda d: d*winfunc(fftlen))
+
+ pylab.show()
+
+if __name__ == "__main__":
+ main()
diff --git a/gr-filter/examples/synth_to_chan.py b/gr-filter/examples/synth_to_chan.py
new file mode 100755
index 0000000000..b5f4c958ef
--- /dev/null
+++ b/gr-filter/examples/synth_to_chan.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python
+#
+# Copyright 2010,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, blks2
+from gnuradio import filter
+import sys
+
+try:
+ import scipy
+except ImportError:
+ print "Error: Program requires scipy (see: www.scipy.org)."
+ sys.exit(1)
+
+try:
+ import pylab
+except ImportError:
+ print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)."
+ sys.exit(1)
+
+def main():
+ N = 1000000
+ fs = 8000
+
+ freqs = [100, 200, 300, 400, 500]
+ nchans = 7
+
+ sigs = list()
+ fmtx = list()
+ for fi in freqs:
+ s = gr.sig_source_f(fs, gr.GR_SIN_WAVE, fi, 1)
+ fm = blks2.nbfm_tx (fs, 4*fs, max_dev=10000, tau=75e-6)
+ sigs.append(s)
+ fmtx.append(fm)
+
+ syntaps = filter.firdes.low_pass_2(len(freqs), fs, fs/float(nchans)/2, 100, 100)
+ print "Synthesis Num. Taps = %d (taps per filter = %d)" % (len(syntaps),
+ len(syntaps)/nchans)
+ chtaps = filter.firdes.low_pass_2(len(freqs), fs, fs/float(nchans)/2, 100, 100)
+ print "Channelizer Num. Taps = %d (taps per filter = %d)" % (len(chtaps),
+ len(chtaps)/nchans)
+ filtbank = filter.pfb_synthesizer_ccf(nchans, syntaps)
+ channelizer = filter.pfb.channelizer_ccf(nchans, chtaps)
+
+ noise_level = 0.01
+ head = gr.head(gr.sizeof_gr_complex, N)
+ noise = gr.noise_source_c(gr.GR_GAUSSIAN, noise_level)
+ addnoise = gr.add_cc()
+ snk_synth = gr.vector_sink_c()
+
+ tb = gr.top_block()
+
+ tb.connect(noise, (addnoise,0))
+ tb.connect(filtbank, head, (addnoise, 1))
+ tb.connect(addnoise, channelizer)
+ tb.connect(addnoise, snk_synth)
+
+ snk = list()
+ for i,si in enumerate(sigs):
+ tb.connect(si, fmtx[i], (filtbank, i))
+
+ for i in xrange(nchans):
+ snk.append(gr.vector_sink_c())
+ tb.connect((channelizer, i), snk[i])
+
+ tb.run()
+
+ if 1:
+ channel = 1
+ data = snk[channel].data()[1000:]
+
+ f1 = pylab.figure(1)
+ s1 = f1.add_subplot(1,1,1)
+ s1.plot(data[10000:10200] )
+ s1.set_title(("Output Signal from Channel %d" % channel))
+
+ fftlen = 2048
+ winfunc = scipy.blackman
+ #winfunc = scipy.hamming
+
+ f2 = pylab.figure(2)
+ s2 = f2.add_subplot(1,1,1)
+ s2.psd(data, NFFT=fftlen,
+ Fs = nchans*fs,
+ noverlap=fftlen/4,
+ window = lambda d: d*winfunc(fftlen))
+ s2.set_title(("Output PSD from Channel %d" % channel))
+
+ f3 = pylab.figure(3)
+ s3 = f3.add_subplot(1,1,1)
+ s3.psd(snk_synth.data()[1000:], NFFT=fftlen,
+ Fs = nchans*fs,
+ noverlap=fftlen/4,
+ window = lambda d: d*winfunc(fftlen))
+ s3.set_title("Output of Synthesis Filter")
+
+ pylab.show()
+
+if __name__ == "__main__":
+ main()
diff --git a/gr-filter/gnuradio-filter.pc.in b/gr-filter/gnuradio-filter.pc.in
new file mode 100644
index 0000000000..e4e83b350c
--- /dev/null
+++ b/gr-filter/gnuradio-filter.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gnuradio-filter
+Description: GNU Radio's filter signal processing blocks
+Requires: gnuradio-core gnuradio-fft
+Version: @LIBVER@
+Libs: -L${libdir} -lgnuradio-filter
+Cflags: -I${includedir}
diff --git a/gr-filter/grc/CMakeLists.txt b/gr-filter/grc/CMakeLists.txt
new file mode 100644
index 0000000000..2e3fef4f07
--- /dev/null
+++ b/gr-filter/grc/CMakeLists.txt
@@ -0,0 +1,41 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+install(FILES
+ filter_block_tree.xml
+ dc_blocker_xx.xml
+ fft_filter_xxx.xml
+ fir_filter_xxx.xml
+ filter_delay_fc.xml
+ fractional_interpolator_xx.xml
+ freq_xlating_fir_filter_xxx.xml
+ hilbert_fc.xml
+ iir_filter_ffd.xml
+ interp_fir_filter_xxx.xml
+ pfb_arb_resampler.xml
+ pfb_channelizer.xml
+ pfb_decimator.xml
+ pfb_interpolator.xml
+ pfb_synthesizer.xml
+ rational_resampler_base_xxx.xml
+ single_pole_iir_filter_xx.xml
+ channel_model.xml
+ DESTINATION ${GRC_BLOCKS_DIR}
+ COMPONENT "filter_python"
+)
diff --git a/gr-filter/grc/channel_model.xml b/gr-filter/grc/channel_model.xml
new file mode 100644
index 0000000000..6d780974a2
--- /dev/null
+++ b/gr-filter/grc/channel_model.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Channel Model
+###################################################
+ -->
+<block>
+ <name>Channel Model</name>
+ <key>channel_model</key>
+ <import>from gnuradio import filter</import>
+ <import>from gnuradio.filter import firdes</import>
+ <make>filter.channel_model(
+ noise_voltage=$noise_voltage,
+ frequency_offset=$freq_offset,
+ epsilon=$epsilon,
+ taps=$taps,
+ noise_seed=$seed,
+)</make>
+ <callback>set_noise_voltage($noise_voltage)</callback>
+ <callback>set_frequency_offset($freq_offset)</callback>
+ <callback>set_taps($taps)</callback>
+ <callback>set_timing_offset($epsilon)</callback>
+ <param>
+ <name>Noise Voltage</name>
+ <key>noise_voltage</key>
+ <value>0.0</value>
+ <type>real</type>
+ </param>
+ <param>
+ <name>Frequency Offset</name>
+ <key>freq_offset</key>
+ <value>0.0</value>
+ <type>real</type>
+ </param>
+ <param>
+ <name>Epsilon</name>
+ <key>epsilon</key>
+ <value>1.0</value>
+ <type>real</type>
+ </param>
+ <param>
+ <name>Taps</name>
+ <key>taps</key>
+ <value>1.0 + 1.0j</value>
+ <type>complex_vector</type>
+ </param>
+ <param>
+ <name>Seed</name>
+ <key>seed</key>
+ <value>0</value>
+ <type>int</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>complex</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>complex</type>
+ </source>
+</block>
diff --git a/gr-filter/grc/dc_blocker_xx.xml b/gr-filter/grc/dc_blocker_xx.xml
new file mode 100644
index 0000000000..9bce5e980b
--- /dev/null
+++ b/gr-filter/grc/dc_blocker_xx.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## DC Blocker
+###################################################
+ -->
+<block>
+ <name>DC Blocker</name>
+ <key>dc_blocker_xx</key>
+ <import>from gnuradio import filter</import>
+ <make>filter.dc_blocker_$(type)($length, $long_form)</make>
+ <!-- <callback>set_length($length)</callback> -->
+ <param>
+ <name>Type</name>
+ <key>type</key>
+ <type>enum</type>
+ <option>
+ <name>Complex->Complex</name>
+ <key>cc</key>
+ <opt>input:complex</opt>
+ <opt>output:complex</opt>
+ </option>
+ <option>
+ <name>Float->Float</name>
+ <key>ff</key>
+ <opt>input:float</opt>
+ <opt>output:float</opt>
+ </option>
+ </param>
+ <param>
+ <name>Length</name>
+ <key>length</key>
+ <value>32</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Long Form</name>
+ <key>long_form</key>
+ <value>True</value>
+ <type>bool</type>
+ </param>
+
+ <sink>
+ <name>in</name>
+ <type>$type.input</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>$type.output</type>
+ </source>
+</block>
diff --git a/gr-filter/grc/fft_filter_xxx.xml b/gr-filter/grc/fft_filter_xxx.xml
new file mode 100644
index 0000000000..29612dffd6
--- /dev/null
+++ b/gr-filter/grc/fft_filter_xxx.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##FFT Filter
+###################################################
+ -->
+<block>
+ <name>FFT Filter</name>
+ <key>fft_filter_xxx</key>
+ <import>from gnuradio import filter</import>
+ <import>from gnuradio.gr import firdes</import>
+ <make>filter.fft_filter_$(type)($decim, $taps, $nthreads)</make>
+ <callback>set_taps($taps)</callback>
+ <callback>set_nthreads($nthreads)</callback>
+ <param>
+ <name>Type</name>
+ <key>type</key>
+ <type>enum</type>
+ <option>
+ <name>Complex->Complex (Complex Taps)</name>
+ <key>ccc</key>
+ <opt>input:complex</opt>
+ <opt>output:complex</opt>
+ <opt>taps:complex_vector</opt>
+ </option>
+ <option>
+ <name>Float->Float (Real Taps)</name>
+ <key>fff</key>
+ <opt>input:float</opt>
+ <opt>output:float</opt>
+ <opt>taps:real_vector</opt>
+ </option>
+ </param>
+ <param>
+ <name>Decimation</name>
+ <key>decim</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Taps</name>
+ <key>taps</key>
+ <type>$type.taps</type>
+ </param>
+ <param>
+ <name>Num. Threads</name>
+ <key>nthreads</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>$type.input</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>$type.output</type>
+ </source>
+</block>
diff --git a/gr-filter/grc/filter_block_tree.xml b/gr-filter/grc/filter_block_tree.xml
new file mode 100644
index 0000000000..711ce4059f
--- /dev/null
+++ b/gr-filter/grc/filter_block_tree.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+
+<!--
+ Copyright 2012 Free Software Foundation, Inc.
+
+ This file is part of GNU Radio
+
+ GNU Radio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GNU Radio is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Radio; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street,
+ Boston, MA 02110-1301, USA.
+-->
+
+<!--
+###################################################
+##Block Tree for GR Filter blocks.
+###################################################
+ -->
+<cat>
+ <name></name> <!-- Blank for Root Name -->
+ <cat>
+ <name>Filters</name>
+ <block>dc_blocker_xx</block>
+ <block>fft_filter_xxx</block>
+ <block>fir_filter_xxx</block>
+ <block>filter_delay_fc</block>
+ <block>fractional_interpolator_xx</block>
+ <block>freq_xlating_fir_filter_xxx</block>
+ <block>hilbert_fc</block>
+ <block>iir_filter_ffd</block>
+ <block>interp_fir_filter_xxx</block>
+ <block>pfb_arb_resampler_xxx</block>
+ <block>pfb_channelizer_ccf</block>
+ <block>pfb_decimator_ccf</block>
+ <block>pfb_interpolator_ccf</block>
+ <block>pfb_synthesizer_ccf</block>
+ <block>rational_resampler_base_xxx</block>
+ <block>single_pole_iir_filter_xx</block>
+ <block>channel_model</block>
+ </cat>
+</cat>
diff --git a/gr-filter/grc/filter_delay_fc.xml b/gr-filter/grc/filter_delay_fc.xml
new file mode 100644
index 0000000000..7b77c2caf9
--- /dev/null
+++ b/gr-filter/grc/filter_delay_fc.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Filter Delay
+###################################################
+ -->
+<block>
+ <name>Filter Delay</name>
+ <key>filter_delay_fc</key>
+ <import>from gnuradio import filter</import>
+ <import>from gnuradio.filter import firdes</import>
+ <make>filter.filter_delay_fc($taps)</make>
+ <param>
+ <name>Taps</name>
+ <key>taps</key>
+ <type>real_vector</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>float</type>
+ </sink>
+ <sink>
+ <name>in</name>
+ <type>float</type>
+ <optional>1</optional>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>complex</type>
+ </source>
+</block>
diff --git a/gr-filter/grc/fir_filter_xxx.xml b/gr-filter/grc/fir_filter_xxx.xml
new file mode 100644
index 0000000000..3925eb5559
--- /dev/null
+++ b/gr-filter/grc/fir_filter_xxx.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Decimating FIR Filter
+###################################################
+ -->
+<block>
+ <name>Decimating FIR Filter</name>
+ <key>fir_filter_xxx</key>
+ <import>from gnuradio import filter</import>
+ <import>from gnuradio.filter import firdes</import>
+ <make>filter.fir_filter_$(type)($decim, $taps)</make>
+ <callback>set_taps($taps)</callback>
+ <param>
+ <name>Type</name>
+ <key>type</key>
+ <type>enum</type>
+ <option>
+ <name>Complex->Complex (Complex Taps)</name>
+ <key>ccc</key>
+ <opt>input:complex</opt>
+ <opt>output:complex</opt>
+ <opt>taps:complex_vector</opt>
+ </option>
+ <option>
+ <name>Complex->Complex (Real Taps)</name>
+ <key>ccf</key>
+ <opt>input:complex</opt>
+ <opt>output:complex</opt>
+ <opt>taps:real_vector</opt>
+ </option>
+ <option>
+ <name>Float->Complex (Complex Taps)</name>
+ <key>fcc</key>
+ <opt>input:float</opt>
+ <opt>output:complex</opt>
+ <opt>taps:complex_vector</opt>
+ </option>
+ <option>
+ <name>Float->Float (Real Taps)</name>
+ <key>fff</key>
+ <opt>input:float</opt>
+ <opt>output:float</opt>
+ <opt>taps:real_vector</opt>
+ </option>
+ <option>
+ <name>Float->Short (Real Taps)</name>
+ <key>fsf</key>
+ <opt>input:float</opt>
+ <opt>output:short</opt>
+ <opt>taps:real_vector</opt>
+ </option>
+ <option>
+ <name>Short->Complex (Complex Taps)</name>
+ <key>scc</key>
+ <opt>input:short</opt>
+ <opt>output:complex</opt>
+ <opt>taps:complex_vector</opt>
+ </option>
+ </param>
+ <param>
+ <name>Decimation</name>
+ <key>decim</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Taps</name>
+ <key>taps</key>
+ <type>$type.taps</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>$type.input</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>$type.output</type>
+ </source>
+</block>
diff --git a/gr-filter/grc/fractional_interpolator_xx.xml b/gr-filter/grc/fractional_interpolator_xx.xml
new file mode 100644
index 0000000000..760e8bb060
--- /dev/null
+++ b/gr-filter/grc/fractional_interpolator_xx.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Fractional Interpolator
+###################################################
+ -->
+<block>
+ <name>Fractional Interpolator</name>
+ <key>fractional_interpolator_xx</key>
+ <import>from gnuradio import filter</import>
+ <make>filter.fractional_interpolator_$(type.fcn)($phase_shift, $interp_ratio)</make>
+ <callback>set_interp_ratio($interp_ratio)</callback>
+ <param>
+ <name>Type</name>
+ <key>type</key>
+ <type>enum</type>
+ <option>
+ <name>Complex</name>
+ <key>complex</key>
+ <opt>fcn:cc</opt>
+ </option>
+ <option>
+ <name>Float</name>
+ <key>float</key>
+ <opt>fcn:ff</opt>
+ </option>
+ </param>
+ <param>
+ <name>Phase Shift</name>
+ <key>phase_shift</key>
+ <type>real</type>
+ </param>
+ <param>
+ <name>Interpolation Ratio</name>
+ <key>interp_ratio</key>
+ <type>real</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>$type</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>$type</type>
+ </source>
+</block>
diff --git a/gr-filter/grc/freq_xlating_fir_filter_xxx.xml b/gr-filter/grc/freq_xlating_fir_filter_xxx.xml
new file mode 100644
index 0000000000..178a42f487
--- /dev/null
+++ b/gr-filter/grc/freq_xlating_fir_filter_xxx.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Frequency Xlating Filter
+###################################################
+ -->
+<block>
+ <name>Frequency Xlating FIR Filter</name>
+ <key>freq_xlating_fir_filter_xxx</key>
+ <import>from gnuradio import filter</import>
+ <import>from gnuradio.filter import firdes</import>
+ <make>filter.freq_xlating_fir_filter_$(type)($decim, $taps, $center_freq, $samp_rate)</make>
+ <callback>set_taps($taps)</callback>
+ <callback>set_center_freq($center_freq)</callback>
+ <param>
+ <name>Type</name>
+ <key>type</key>
+ <type>enum</type>
+ <option>
+ <name>Complex->Complex (Complex Taps)</name>
+ <key>ccc</key>
+ <opt>input:complex</opt>
+ <opt>output:complex</opt>
+ <opt>taps:complex_vector</opt>
+ </option>
+ <option>
+ <name>Complex->Complex (Real Taps)</name>
+ <key>ccf</key>
+ <opt>input:complex</opt>
+ <opt>output:complex</opt>
+ <opt>taps:real_vector</opt>
+ </option>
+ <option>
+ <name>Float->Complex (Complex Taps)</name>
+ <key>fcc</key>
+ <opt>input:float</opt>
+ <opt>output:complex</opt>
+ <opt>taps:complex_vector</opt>
+ </option>
+ <option>
+ <name>Float->Complex (Real Taps)</name>
+ <key>fcf</key>
+ <opt>input:float</opt>
+ <opt>output:complex</opt>
+ <opt>taps:real_vector</opt>
+ </option>
+ <option>
+ <name>Short->Complex (Complex Taps)</name>
+ <key>scc</key>
+ <opt>input:short</opt>
+ <opt>output:complex</opt>
+ <opt>taps:complex_vector</opt>
+ </option>
+ <option>
+ <name>Short->Complex (Real Taps)</name>
+ <key>scf</key>
+ <opt>input:short</opt>
+ <opt>output:complex</opt>
+ <opt>taps:real_vector</opt>
+ </option>
+ </param>
+ <param>
+ <name>Decimation</name>
+ <key>decim</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Taps</name>
+ <key>taps</key>
+ <type>$type.taps</type>
+ </param>
+ <param>
+ <name>Center Frequency</name>
+ <key>center_freq</key>
+ <value>0</value>
+ <type>real</type>
+ </param>
+ <param>
+ <name>Sample Rate</name>
+ <key>samp_rate</key>
+ <value>samp_rate</value>
+ <type>real</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>$type.input</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>$type.output</type>
+ </source>
+</block>
diff --git a/grc/blocks/gr_diff_decoder_bb.xml b/gr-filter/grc/hilbert_fc.xml
index ea7cf17343..dd4c94b831 100644
--- a/grc/blocks/gr_diff_decoder_bb.xml
+++ b/gr-filter/grc/hilbert_fc.xml
@@ -1,25 +1,26 @@
<?xml version="1.0"?>
<!--
###################################################
-##Differential Decoder
+##Hilbert
###################################################
-->
<block>
- <name>Differential Decoder</name>
- <key>gr_diff_decoder_bb</key>
- <import>from gnuradio import gr</import>
- <make>gr.diff_decoder_bb($modulus)</make>
+ <name>Hilbert</name>
+ <key>hilbert_fc</key>
+ <import>from gnuradio import filter</import>
+ <make>filter.hilbert_fc($num_taps)</make>
<param>
- <name>Modulus</name>
- <key>modulus</key>
+ <name>Num Taps</name>
+ <key>num_taps</key>
+ <value>64</value>
<type>int</type>
</param>
<sink>
<name>in</name>
- <type>byte</type>
+ <type>float</type>
</sink>
<source>
<name>out</name>
- <type>byte</type>
+ <type>complex</type>
</source>
</block>
diff --git a/gr-filter/grc/iir_filter_ffd.xml b/gr-filter/grc/iir_filter_ffd.xml
new file mode 100644
index 0000000000..261aba320c
--- /dev/null
+++ b/gr-filter/grc/iir_filter_ffd.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##IIR Filter
+###################################################
+ -->
+<block>
+ <name>IIR Filter</name>
+ <key>iir_filter_ffd</key>
+ <import>from gnuradio import filter</import>
+ <make>filter.iir_filter_ffd($fftaps, $fbtaps)</make>
+ <callback>set_taps($fftaps, $fbtaps)</callback>
+ <param>
+ <name>Feed-forward Taps</name>
+ <key>fftaps</key>
+ <type>real_vector</type>
+ </param>
+ <param>
+ <name>Feedback Taps</name>
+ <key>fbtaps</key>
+ <type>real_vector</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>float</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>float</type>
+ </source>
+</block>
diff --git a/gr-filter/grc/interp_fir_filter_xxx.xml b/gr-filter/grc/interp_fir_filter_xxx.xml
new file mode 100644
index 0000000000..98a143f538
--- /dev/null
+++ b/gr-filter/grc/interp_fir_filter_xxx.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Interpolating FIR Filter
+###################################################
+ -->
+<block>
+ <name>Interpolating FIR Filter</name>
+ <key>interp_fir_filter_xxx</key>
+ <import>from gnuradio import filter</import>
+ <import>from gnuradio.filter import firdes</import>
+ <make>filter.interp_fir_filter_$(type)($interp, $taps)</make>
+ <callback>set_taps($taps)</callback>
+ <param>
+ <name>Type</name>
+ <key>type</key>
+ <type>enum</type>
+ <option>
+ <name>Complex->Complex (Complex Taps)</name>
+ <key>ccc</key>
+ <opt>input:complex</opt>
+ <opt>output:complex</opt>
+ <opt>taps:complex_vector</opt>
+ </option>
+ <option>
+ <name>Complex->Complex (Real Taps)</name>
+ <key>ccf</key>
+ <opt>input:complex</opt>
+ <opt>output:complex</opt>
+ <opt>taps:real_vector</opt>
+ </option>
+ <option>
+ <name>Float->Complex (Complex Taps)</name>
+ <key>fcc</key>
+ <opt>input:float</opt>
+ <opt>output:complex</opt>
+ <opt>taps:complex_vector</opt>
+ </option>
+ <option>
+ <name>Float->Float (Real Taps)</name>
+ <key>fff</key>
+ <opt>input:float</opt>
+ <opt>output:float</opt>
+ <opt>taps:real_vector</opt>
+ </option>
+ <option>
+ <name>Float->Short (Real Taps)</name>
+ <key>fsf</key>
+ <opt>input:float</opt>
+ <opt>output:short</opt>
+ <opt>taps:real_vector</opt>
+ </option>
+ <option>
+ <name>Short->Complex (Complex Taps)</name>
+ <key>scc</key>
+ <opt>input:short</opt>
+ <opt>output:complex</opt>
+ <opt>taps:complex_vector</opt>
+ </option>
+ </param>
+ <param>
+ <name>Interpolation</name>
+ <key>interp</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Taps</name>
+ <key>taps</key>
+ <type>$type.taps</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>$type.input</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>$type.output</type>
+ </source>
+</block>
diff --git a/gr-filter/grc/pfb_arb_resampler.xml b/gr-filter/grc/pfb_arb_resampler.xml
new file mode 100644
index 0000000000..f3048000ac
--- /dev/null
+++ b/gr-filter/grc/pfb_arb_resampler.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Polyphase Arbitrary Resampler
+###################################################
+ -->
+<block>
+ <name>Polyphase Arbitrary Resampler</name>
+ <key>pfb_arb_resampler_xxx</key>
+ <import>from gnuradio import filter</import>
+ <import>from gnuradio.filter import firdes</import>
+ <make>filter.pfb_arb_resampler_$(type)(
+ $rrate,
+ $taps,
+ $nfilts)
+ </make>
+ <callback>set_taps($taps)</callback>
+ <param>
+ <name>Type</name>
+ <key>type</key>
+ <type>enum</type>
+ <option>
+ <name>Complex->Complex (Real Taps)</name>
+ <key>ccf</key>
+ <opt>input:complex</opt>
+ <opt>output:complex</opt>
+ <opt>taps:real_vector</opt>
+ </option>
+ <option>
+ <name>Float->Float (Real Taps)</name>
+ <key>fff</key>
+ <opt>input:float</opt>
+ <opt>output:float</opt>
+ <opt>taps:real_vector</opt>
+ </option>
+ </param>
+ <param>
+ <name>Resampling Rate</name>
+ <key>rrate</key>
+ <type>real</type>
+ </param>
+ <param>
+ <name>Taps</name>
+ <key>taps</key>
+ <type>$type.taps</type>
+ </param>
+ <param>
+ <name>Number of Filters</name>
+ <key>nfilts</key>
+ <value>32</value>
+ <type>int</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>complex</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>complex</type>
+ </source>
+</block>
diff --git a/gr-filter/grc/pfb_channelizer.xml b/gr-filter/grc/pfb_channelizer.xml
new file mode 100644
index 0000000000..114abc0f06
--- /dev/null
+++ b/gr-filter/grc/pfb_channelizer.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Polyphase Channelizer
+###################################################
+ -->
+<block>
+ <name>Polyphase Channelizer</name>
+ <key>pfb_channelizer_ccf</key>
+ <import>from gnuradio import filter</import>
+ <import>from gnuradio.filter import firdes</import>
+ <make>filter.pfb.channelizer_ccf(
+ $nchans,
+ $taps,
+ $osr,
+ $atten)
+self.$(id).set_channel_map($ch_map)
+ </make>
+ <!-- Set taps not implemented yet
+ <callback>set_taps($taps)</callback>
+ -->
+ <callback>set_channel_map($ch_map)</callback>
+
+ <param>
+ <name>Channels</name>
+ <key>nchans</key>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Taps</name>
+ <key>taps</key>
+ <value>None</value>
+ <type>real_vector</type>
+ </param>
+ <param>
+ <name>Over Sample Ratio</name>
+ <key>osr</key>
+ <value>1.0</value>
+ <type>real</type>
+ </param>
+ <param>
+ <name>Attenuation</name>
+ <key>atten</key>
+ <value>100</value>
+ <type>real</type>
+ </param>
+ <param>
+ <name>Channel Map</name>
+ <key>ch_map</key>
+ <value>[]</value>
+ <type>int_vector</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>complex</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>complex</type>
+ <nports>$nchans</nports>
+ </source>
+</block>
diff --git a/gr-filter/grc/pfb_decimator.xml b/gr-filter/grc/pfb_decimator.xml
new file mode 100644
index 0000000000..b0540d3e2c
--- /dev/null
+++ b/gr-filter/grc/pfb_decimator.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Polyphase Decimator
+###################################################
+ -->
+<block>
+ <name>Polyphase Decimator</name>
+ <key>pfb_decimator_ccf</key>
+ <import>from gnuradio import filter</import>
+ <import>from gnuradio.filter import firdes</import>
+ <make>filter.pfb_decimator_ccf(
+ $decim,
+ $taps,
+ $channel)
+ </make>
+ <callback>set_taps($taps)</callback>
+ <param>
+ <name>Decimation</name>
+ <key>decim</key>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Taps</name>
+ <key>taps</key>
+ <value>None</value>
+ <type>real_vector</type>
+ </param>
+ <param>
+ <name>Output Channel</name>
+ <key>channel</key>
+ <value>0</value>
+ <type>int</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>complex</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>complex</type>
+ </source>
+</block>
diff --git a/gr-filter/grc/pfb_interpolator.xml b/gr-filter/grc/pfb_interpolator.xml
new file mode 100644
index 0000000000..6004931235
--- /dev/null
+++ b/gr-filter/grc/pfb_interpolator.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Polyphase Interpolator
+###################################################
+ -->
+<block>
+ <name>Polyphase Interpolator</name>
+ <key>pfb_interpolator_ccf</key>
+ <import>from gnuradio import filter</import>
+ <import>from gnuradio.filter import firdes</import>
+ <make>filter.pfb.interpolator_ccf(
+ $interp,
+ $taps)
+ </make>
+ <callback>set_taps($taps)</callback>
+ <param>
+ <name>Interpolation</name>
+ <key>interp</key>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Taps</name>
+ <key>taps</key>
+ <value>None</value>
+ <type>real_vector</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>complex</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>complex</type>
+ </source>
+</block>
diff --git a/gr-filter/grc/pfb_synthesizer.xml b/gr-filter/grc/pfb_synthesizer.xml
new file mode 100644
index 0000000000..e84b25e62e
--- /dev/null
+++ b/gr-filter/grc/pfb_synthesizer.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Polyphase Synthesis Filterbank
+###################################################
+ -->
+<block>
+ <name>Polyphase Synthesizer</name>
+ <key>pfb_synthesizer_ccf</key>
+ <import>from gnuradio import filter</import>
+ <import>from gnuradio.filter import firdes</import>
+ <make>filter.pfb_synthesizer_ccf(
+ $numchans, $taps, $twox)
+self.$(id).set_channel_map($ch_map)
+ </make>
+ <callback>set_taps($taps)</callback>
+ <callback>set_channel_map($ch_map)</callback>
+
+ <param>
+ <name>Channels</name>
+ <key>numchans</key>
+ <value>2</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Connections</name>
+ <key>connections</key>
+ <value>2</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Taps</name>
+ <key>taps</key>
+ <type>real_vector</type>
+ </param>
+ <param>
+ <name>2x Sample Rate</name>
+ <key>twox</key>
+ <value>False</value>
+ <type>bool</type>
+ </param>
+ <param>
+ <name>Channel Map</name>
+ <key>ch_map</key>
+ <value>[]</value>
+ <type>int_vector</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>complex</type>
+ <nports>$connections</nports>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>complex</type>
+ </source>
+</block>
diff --git a/gr-filter/grc/rational_resampler_base_xxx.xml b/gr-filter/grc/rational_resampler_base_xxx.xml
new file mode 100644
index 0000000000..399bfc74c9
--- /dev/null
+++ b/gr-filter/grc/rational_resampler_base_xxx.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Rational Resampler Base
+###################################################
+ -->
+<block>
+ <name>Rational Resampler Base</name>
+ <key>rational_resampler_base_xxx</key>
+ <import>from gnuradio import filter</import>
+ <import>from gnuradio.filter import firdes</import>
+ <make>filter.rational_resampler_base_$(type)($interp, $decim, $taps)</make>
+ <callback>set_taps($taps)</callback>
+ <param>
+ <name>Type</name>
+ <key>type</key>
+ <type>enum</type>
+ <option>
+ <name>Complex->Complex (Complex Taps)</name>
+ <key>ccc</key>
+ <opt>input:complex</opt>
+ <opt>output:complex</opt>
+ <opt>taps:complex_vector</opt>
+ </option>
+ <option>
+ <name>Complex->Complex (Real Taps)</name>
+ <key>ccf</key>
+ <opt>input:complex</opt>
+ <opt>output:complex</opt>
+ <opt>taps:real_vector</opt>
+ </option>
+ <option>
+ <name>Float->Complex (Complex Taps)</name>
+ <key>fcc</key>
+ <opt>input:float</opt>
+ <opt>output:complex</opt>
+ <opt>taps:complex_vector</opt>
+ </option>
+ <option>
+ <name>Float->Float (Real Taps)</name>
+ <key>fff</key>
+ <opt>input:float</opt>
+ <opt>output:float</opt>
+ <opt>taps:real_vector</opt>
+ </option>
+ <option>
+ <name>Float->Short (Real Taps)</name>
+ <key>fsf</key>
+ <opt>input:float</opt>
+ <opt>output:short</opt>
+ <opt>taps:real_vector</opt>
+ </option>
+ <option>
+ <name>Short->Complex (Complex Taps)</name>
+ <key>scc</key>
+ <opt>input:short</opt>
+ <opt>output:complex</opt>
+ <opt>taps:complex_vector</opt>
+ </option>
+ </param>
+ <param>
+ <name>Interpolation</name>
+ <key>interp</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Decimation</name>
+ <key>decim</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Taps</name>
+ <key>taps</key>
+ <type>$type.taps</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>$type.input</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>$type.output</type>
+ </source>
+</block>
diff --git a/gr-filter/grc/single_pole_iir_filter_xx.xml b/gr-filter/grc/single_pole_iir_filter_xx.xml
new file mode 100644
index 0000000000..3eaf52625f
--- /dev/null
+++ b/gr-filter/grc/single_pole_iir_filter_xx.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Single Pole IIR Filter
+###################################################
+ -->
+<block>
+ <name>Single Pole IIR Filter</name>
+ <key>single_pole_iir_filter_xx</key>
+ <import>from gnuradio import filter</import>
+ <make>filter.single_pole_iir_filter_$(type.fcn)($alpha, $vlen)</make>
+ <callback>set_taps($alpha)</callback>
+ <param>
+ <name>Type</name>
+ <key>type</key>
+ <type>enum</type>
+ <option>
+ <name>Complex</name>
+ <key>complex</key>
+ <opt>fcn:cc</opt>
+ </option>
+ <option>
+ <name>Float</name>
+ <key>float</key>
+ <opt>fcn:ff</opt>
+ </option>
+ </param>
+ <param>
+ <name>Alpha</name>
+ <key>alpha</key>
+ <value>1.0</value>
+ <type>real</type>
+ </param>
+ <param>
+ <name>Vec Length</name>
+ <key>vlen</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <check>$vlen &gt; 0</check>
+ <sink>
+ <name>in</name>
+ <type>$type</type>
+ <vlen>$vlen</vlen>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>$type</type>
+ <vlen>$vlen</vlen>
+ </source>
+</block>
diff --git a/gr-filter/include/filter/CMakeLists.txt b/gr-filter/include/filter/CMakeLists.txt
new file mode 100644
index 0000000000..c6bf109cde
--- /dev/null
+++ b/gr-filter/include/filter/CMakeLists.txt
@@ -0,0 +1,116 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+# generate helper scripts to expand templated files
+########################################################################
+include(GrPython)
+
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py "
+#!${PYTHON_EXECUTABLE}
+
+import sys, os, re
+sys.path.append('${GR_CORE_PYTHONPATH}')
+os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
+os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
+
+if __name__ == '__main__':
+ import build_utils
+ root, inp = sys.argv[1:3]
+ for sig in sys.argv[3:]:
+ name = re.sub ('X+', sig, root)
+ d = build_utils.standard_dict2(name, sig, 'filter')
+ build_utils.expand_template(d, inp)
+
+")
+
+macro(expand_h root)
+ #make a list of all the generated files
+ unset(expanded_files_h)
+ foreach(sig ${ARGN})
+ string(REGEX REPLACE "X+" ${sig} name ${root})
+ list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/${name}.h)
+ endforeach(sig)
+
+ #create a command to generate the files
+ add_custom_command(
+ OUTPUT ${expanded_files_h}
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t
+ COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
+ ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
+ ${root} ${root}.h.t ${ARGN}
+ )
+
+ #install rules for the generated h files
+ list(APPEND generated_includes ${expanded_files_h})
+endmacro(expand_h)
+
+########################################################################
+# Invoke macro to generate various sources
+#######################################################################
+expand_h(fir_filter_XXX ccc ccf fcc fff fsf scc)
+expand_h(freq_xlating_fir_filter_XXX ccc ccf fcc fcf scf scc)
+expand_h(interp_fir_filter_XXX ccc ccf fcc fff fsf scc)
+expand_h(rational_resampler_base_XXX ccc ccf fcc fff fsf scc)
+
+add_custom_target(filter_generated_includes DEPENDS
+ ${generated_includes}
+)
+
+########################################################################
+# Install header files
+########################################################################
+install(FILES
+ api.h
+ firdes.h
+ fir_filter.h
+ fir_filter_with_buffer.h
+ fft_filter.h
+ iir_filter.h
+ interpolator_taps.h
+ mmse_fir_interpolator_cc.h
+ mmse_fir_interpolator_ff.h
+ pm_remez.h
+ polyphase_filterbank.h
+ single_pole_iir.h
+ ${generated_includes}
+ adaptive_fir_ccc.h
+ adaptive_fir_ccf.h
+ dc_blocker_cc.h
+ dc_blocker_ff.h
+ filter_delay_fc.h
+ fft_filter_ccc.h
+ fft_filter_fff.h
+ fractional_interpolator_cc.h
+ fractional_interpolator_ff.h
+ hilbert_fc.h
+ iir_filter_ffd.h
+ pfb_arb_resampler_ccf.h
+ pfb_arb_resampler_fff.h
+ pfb_channelizer_ccf.h
+ pfb_decimator_ccf.h
+ pfb_interpolator_ccf.h
+ pfb_synthesizer_ccf.h
+ single_pole_iir_filter_cc.h
+ single_pole_iir_filter_ff.h
+ channel_model.h
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio/filter
+ COMPONENT "filter_devel"
+)
+
diff --git a/gr-filter/include/filter/adaptive_fir_ccc.h b/gr-filter/include/filter/adaptive_fir_ccc.h
new file mode 100644
index 0000000000..261259957f
--- /dev/null
+++ b/gr-filter/include/filter/adaptive_fir_ccc.h
@@ -0,0 +1,85 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_FILTER_ADAPTIVE_FIR_CCC_H
+#define INCLUDED_FILTER_ADAPTIVE_FIR_CCC_H
+
+#include <filter/api.h>
+#include <gr_sync_decimator.h>
+#include <filter/fir_filter.h>
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \brief Adaptive FIR filter with gr_complex input, gr_complex output and gr_complex taps
+ * \ingroup filter_blk
+ *
+ * This is a base class to implement an adaptive FIR
+ * filter. Generally, another block will inherit from this one to
+ * build a new type of adaptive filter such as an equalizer.
+ *
+ * This class implements two functions that are designed to be
+ * overloaded by the child class: error(gr_complex out) and
+ * update_tap(gr_complex tap, gr_complex in).
+ *
+ * The error() function calculates the error value that will be
+ * used to adjust the taps. The update_tap function then uses the
+ * error and the input signal value to update a particular
+ * tap. Typically, the error is calculated for a given output and
+ * then this is used in a loop to update all of the filter taps in
+ * a loop:
+ *
+ * \code
+ * d_error = error(sum);
+ * for(k = 0; k < l; k++) {
+ * update_tap(d_taps[ntaps-k-1], in[i+k]);
+ * }
+ * \endcode
+ *
+ * See digital::cma_equalizer_cc and digital::lms_dd_equalizer_cc
+ * for example usage.
+ */
+ class FILTER_API adaptive_fir_ccc : virtual public gr_sync_decimator
+ {
+ public:
+ // gr::filter::adaptive_fir_ccc::sptr
+ typedef boost::shared_ptr<adaptive_fir_ccc> sptr;
+
+ /*!
+ * \brief Adaptive FIR filter with gr_complex input, gr_complex output and gr_complex taps
+ *
+ * \param name Provides a name to identify this type of algorithm
+ * \param decimation (interger) decimation rate of the filter
+ * \param taps (complex) filter taps
+ */
+ static sptr make(const char *name, int decimation,
+ const std::vector<gr_complex> &taps);
+
+ virtual void set_taps(const std::vector<gr_complex> &taps) = 0;
+ virtual std::vector<gr_complex> taps() const = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_ADAPTIVE_FIR_CCC_H */
diff --git a/gr-filter/include/filter/adaptive_fir_ccf.h b/gr-filter/include/filter/adaptive_fir_ccf.h
new file mode 100644
index 0000000000..0fd8d5746a
--- /dev/null
+++ b/gr-filter/include/filter/adaptive_fir_ccf.h
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_FILTER_ADAPTIVE_FIR_CCF_H
+#define INCLUDED_FILTER_ADAPTIVE_FIR_CCF_H
+
+#include <filter/api.h>
+#include <gr_sync_decimator.h>
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \brief Adaptive FIR filter with gr_complex input, gr_complex output and float taps
+ * \ingroup filter_blk
+ *
+ * This is a base class to implement an adaptive FIR
+ * filter. Generally, another block will inherit from this one to
+ * build a new type of adaptive filter such as an equalizer.
+ *
+ * This class implements two functions that are designed to be
+ * overloaded by the child class: error(gr_complex out) and
+ * update_tap(float tap, gr_complex in).
+ *
+ * The error() function calculates the error value that will be
+ * used to adjust the taps. The update_tap function then uses the
+ * error and the input signal value to update a particular
+ * tap. Typically, the error is calculated for a given output and
+ * then this is used in a loop to update all of the filter taps in
+ * a loop:
+ *
+ * \code
+ * d_error = error(sum);
+ * for(k = 0; k < l; k++) {
+ * update_tap(d_taps[ntaps-k-1], in[i+k]);
+ * }
+ * \endcode
+ */
+ class FILTER_API adaptive_fir_ccf : virtual public gr_sync_decimator
+ {
+ public:
+ // gr::filter::adaptive_fir_ccf::sptr
+ typedef boost::shared_ptr<adaptive_fir_ccf> sptr;
+
+ /*!
+ * \brief Adaptive FIR filter with gr_complex input, gr_complex output and float taps
+ *
+ * \param name Provides a name to identify this type of algorithm
+ * \param decimation (interger) decimation rate of the filter
+ * \param taps (real) filter taps
+ */
+ static sptr make(const char *name, int decimation,
+ const std::vector<float> &taps);
+
+ virtual void set_taps(const std::vector<float> &taps) = 0;
+ virtual std::vector<float> taps() = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_ADAPTIVE_FIR_CCF_H */
diff --git a/gnuradio-core/src/lib/general/gr_diff_encoder_bb.i b/gr-filter/include/filter/api.h
index 96dadaca5b..025b0bd4a7 100644
--- a/gnuradio-core/src/lib/general/gr_diff_encoder_bb.i
+++ b/gr-filter/include/filter/api.h
@@ -1,6 +1,5 @@
-/* -*- c++ -*- */
/*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -20,12 +19,15 @@
* Boston, MA 02110-1301, USA.
*/
-GR_SWIG_BLOCK_MAGIC(gr,diff_encoder_bb)
+#ifndef INCLUDED_FILTER_API_H
+#define INCLUDED_FILTER_API_H
-gr_diff_encoder_bb_sptr gr_make_diff_encoder_bb (unsigned int modulus);
+#include <gruel/attributes.h>
-class gr_diff_encoder_bb : public gr_sync_block
-{
- private:
- gr_diff_encoder_bb (unsigned int modulus);
-};
+#ifdef gnuradio_filter_EXPORTS
+# define FILTER_API __GR_ATTR_EXPORT
+#else
+# define FILTER_API __GR_ATTR_IMPORT
+#endif
+
+#endif /* INCLUDED_FILTER_API_H */
diff --git a/gr-filter/include/filter/channel_model.h b/gr-filter/include/filter/channel_model.h
new file mode 100644
index 0000000000..2e808de8e5
--- /dev/null
+++ b/gr-filter/include/filter/channel_model.h
@@ -0,0 +1,87 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_FILTER_CHANNEL_MODEL_H
+#define INCLUDED_FILTER_CHANNEL_MODEL_H
+
+#include <filter/api.h>
+#include <gr_hier_block2.h>
+#include <gr_types.h>
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \brief channel simulator
+ * \ingroup misc_blk
+ *
+ * This block implements a basic channel model simulator that can
+ * be used to help evaluate, design, and test various signals,
+ * waveforms, and algorithms. This model allows the user to set
+ * the voltage of an AWGN noise source, a (normalized) frequency
+ * offset, a sample timing offset, and a noise seed to randomize
+ * the AWGN noise source.
+ *
+ * Multipath can be approximated in this model by using a FIR
+ * filter representation of a multipath delay profile..
+ */
+ class FILTER_API channel_model : virtual public gr_hier_block2
+ {
+ public:
+ // gr::filter::channel_model::sptr
+ typedef boost::shared_ptr<channel_model> sptr;
+
+ /*! \brief Build the channel simulator.
+ *
+ * \param noise_voltage The AWGN noise level as a voltage (to be
+ * calculated externally to meet, say, a
+ * desired SNR).
+ * \param frequency_offset The normalized frequency offset. 0 is
+ * no offset; 0.25 would be, for a digital
+ * modem, one quarter of the symbol rate.
+ * \param epsilon The sample timing offset to emulate the
+ * different rates between the sample clocks of
+ * the transmitter and receiver. 1.0 is no difference.
+ * \param taps Taps of a FIR filter to emulate a multipath delay profile.
+ * \param noise_seed A random number generator seed for the noise source.
+ */
+ static sptr make(double noise_voltage=0.0,
+ double frequency_offset=0.0,
+ double epsilon=1.0,
+ const std::vector<gr_complex> &taps=std::vector<gr_complex>(1,1),
+ double noise_seed=3021);
+
+ virtual void set_noise_voltage(double noise_voltage) = 0;
+ virtual void set_frequency_offset(double frequency_offset) = 0;
+ virtual void set_taps(const std::vector<gr_complex> &taps) = 0;
+ virtual void set_timing_offset(double epsilon) = 0;
+
+ virtual double noise_voltage() const = 0;
+ virtual double frequency_offset() const = 0;
+ virtual std::vector<gr_complex> taps() const = 0;
+ virtual double timing_offset() const = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_CHANNEL_MODEL_H */
diff --git a/gr-filter/include/filter/dc_blocker_cc.h b/gr-filter/include/filter/dc_blocker_cc.h
new file mode 100644
index 0000000000..df4c815d60
--- /dev/null
+++ b/gr-filter/include/filter/dc_blocker_cc.h
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_FILTER_DC_BLOCKER_CC_H
+#define INCLUDED_FILTER_DC_BLOCKER_CC_H
+
+#include <filter/api.h>
+#include <gr_sync_block.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API dc_blocker_cc : virtual public gr_sync_block
+ {
+ public:
+
+ // gr::filter::dc_blocker_cc::sptr
+ typedef boost::shared_ptr<dc_blocker_cc> sptr;
+
+ /*!
+ * \class dc_blocker_cc
+ * \brief a computationally efficient controllable DC blocker
+ *
+ * \ingroup filter_blk
+ *
+ * This block implements a computationally efficient DC blocker that produces
+ * a tighter notch filter around DC for a smaller group delay than an
+ * equivalent FIR filter or using a single pole IIR filter (though the IIR
+ * filter is computationally cheaper).
+ *
+ * The block defaults to using a delay line of length 32 and the long form
+ * of the filter. Optionally, the delay line length can be changed to alter
+ * the width of the DC notch (longer lines will decrease the width).
+ *
+ * The long form of the filter produces a nearly flat response outside of
+ * the notch but at the cost of a group delay of 2D-2.
+ *
+ * The short form of the filter does not have as flat a response in the
+ * passband but has a group delay of only D-1 and is cheaper to compute.
+ *
+ * The theory behind this block can be found in the paper:
+ *
+ * <B><EM>R. Yates, "DC Blocker Algorithms," IEEE Signal Processing Magazine,
+ * Mar. 2008, pp 132-134.</EM></B>
+ *
+ * \param D (int) the length of the delay line
+ * \param long_form (bool) whether to use long (true, default) or short form
+ */
+ static sptr make(int D, bool long_form);
+
+ virtual int group_delay() = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_DC_BLOCKER_CC_H */
diff --git a/gr-filter/include/filter/dc_blocker_ff.h b/gr-filter/include/filter/dc_blocker_ff.h
new file mode 100644
index 0000000000..6ab4d5a3de
--- /dev/null
+++ b/gr-filter/include/filter/dc_blocker_ff.h
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_FILTER_DC_BLOCKER_FF_H
+#define INCLUDED_FILTER_DC_BLOCKER_FF_H
+
+#include <filter/api.h>
+#include <gr_sync_block.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API dc_blocker_ff : virtual public gr_sync_block
+ {
+ public:
+
+ // gr::filter::dc_blocker_ff::sptr
+ typedef boost::shared_ptr<dc_blocker_ff> sptr;
+
+ /*!
+ * \class dc_blocker_ff
+ * \brief a computationally efficient controllable DC blocker
+ *
+ * \ingroup filter_blk
+ *
+ * This block implements a computationally efficient DC blocker that produces
+ * a tighter notch filter around DC for a smaller group delay than an
+ * equivalent FIR filter or using a single pole IIR filter (though the IIR
+ * filter is computationally cheaper).
+ *
+ * The block defaults to using a delay line of length 32 and the long form
+ * of the filter. Optionally, the delay line length can be changed to alter
+ * the width of the DC notch (longer lines will decrease the width).
+ *
+ * The long form of the filter produces a nearly flat response outside of
+ * the notch but at the cost of a group delay of 2D-2.
+ *
+ * The short form of the filter does not have as flat a response in the
+ * passband but has a group delay of only D-1 and is cheaper to compute.
+ *
+ * The theory behind this block can be found in the paper:
+ *
+ * <B><EM>R. Yates, "DC Blocker Algorithms," IEEE Signal Processing Magazine,
+ * Mar. 2008, pp 132-134.</EM></B>
+ *
+ * \param D (int) the length of the delay line
+ * \param long_form (bool) whether to use long (true, default) or short form
+ */
+ static sptr make(int D, bool long_form=true);
+
+ virtual int group_delay() = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_DC_BLOCKER_FF_H */
diff --git a/gr-filter/include/filter/fft_filter.h b/gr-filter/include/filter/fft_filter.h
new file mode 100644
index 0000000000..8c7d6cf786
--- /dev/null
+++ b/gr-filter/include/filter/fft_filter.h
@@ -0,0 +1,171 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_FILTER_FFT_FILTER_H
+#define INCLUDED_FILTER_FFT_FILTER_H
+
+#include <filter/api.h>
+#include <vector>
+#include <gr_complex.h>
+#include <fft/fft.h>
+
+namespace gr {
+ namespace filter {
+ namespace kernel {
+ /*!
+ * \brief Fast FFT filter with float input, float output and float taps
+ * \ingroup filter_blk
+ */
+ class FILTER_API fft_filter_fff
+ {
+ private:
+ int d_ntaps;
+ int d_nsamples;
+ int d_fftsize; // fftsize = ntaps + nsamples - 1
+ int d_decimation;
+ fft::fft_real_fwd *d_fwdfft; // forward "plan"
+ fft::fft_real_rev *d_invfft; // inverse "plan"
+ int d_nthreads; // number of FFTW threads to use
+ std::vector<float> d_tail; // state carried between blocks for overlap-add
+ std::vector<float> d_new_taps;
+ gr_complex *d_xformed_taps; // Fourier xformed taps
+
+ void compute_sizes(int ntaps);
+ int tailsize() const { return d_ntaps - 1; }
+
+ public:
+ /*!
+ * \brief Construct an FFT filter for float vectors with the given taps and decimation rate.
+ *
+ * This is the basic implementation for performing FFT filter for fast convolution
+ * in other blocks for complex vectors (such as fft_filter_ccc).
+ *
+ * \param decimation The decimation rate of the filter (int)
+ * \param taps The filter taps (complex)
+ * \param nthreads The number of threads for the FFT to use (int)
+ */
+ fft_filter_fff(int decimation,
+ const std::vector<float> &taps,
+ int nthreads=1);
+
+ ~fft_filter_fff();
+
+ /*!
+ * \brief Set new taps for the filter.
+ *
+ * Sets new taps and resets the class properties to handle different sizes
+ * \param taps The filter taps (complex)
+ */
+ int set_taps(const std::vector<float> &taps);
+
+ /*!
+ * \brief Set number of threads to use.
+ */
+ void set_nthreads(int n);
+
+ /*!
+ * \brief Get number of threads being used.
+ */
+ int nthreads() const;
+
+ /*!
+ * \brief Perform the filter operation
+ *
+ * \param nitems The number of items to produce
+ * \param input The input vector to be filtered
+ * \param output The result of the filter operation
+ */
+ int filter(int nitems, const float *input, float *output);
+ };
+
+
+ /*!
+ * \brief Fast FFT filter with gr_complex input, gr_complex output and gr_complex taps
+ * \ingroup filter_blk
+ */
+ class FILTER_API fft_filter_ccc
+ {
+ private:
+ int d_ntaps;
+ int d_nsamples;
+ int d_fftsize; // fftsize = ntaps + nsamples - 1
+ int d_decimation;
+ fft::fft_complex *d_fwdfft; // forward "plan"
+ fft::fft_complex *d_invfft; // inverse "plan"
+ int d_nthreads; // number of FFTW threads to use
+ std::vector<gr_complex> d_tail; // state carried between blocks for overlap-add
+ std::vector<gr_complex> d_new_taps;
+ gr_complex *d_xformed_taps; // Fourier xformed taps
+
+ void compute_sizes(int ntaps);
+ int tailsize() const { return d_ntaps - 1; }
+
+ public:
+ /*!
+ * \brief Construct an FFT filter for complex vectors with the given taps and decimation rate.
+ *
+ * This is the basic implementation for performing FFT filter for fast convolution
+ * in other blocks for complex vectors (such as fft_filter_ccc).
+ *
+ * \param decimation The decimation rate of the filter (int)
+ * \param taps The filter taps (complex)
+ * \param nthreads The number of threads for the FFT to use (int)
+ */
+ fft_filter_ccc(int decimation,
+ const std::vector<gr_complex> &taps,
+ int nthreads=1);
+
+ ~fft_filter_ccc();
+
+ /*!
+ * \brief Set new taps for the filter.
+ *
+ * Sets new taps and resets the class properties to handle different sizes
+ * \param taps The filter taps (complex)
+ */
+ int set_taps(const std::vector<gr_complex> &taps);
+
+ /*!
+ * \brief Set number of threads to use.
+ */
+ void set_nthreads(int n);
+
+ /*!
+ * \brief Get number of threads being used.
+ */
+ int nthreads() const;
+
+ /*!
+ * \brief Perform the filter operation
+ *
+ * \param nitems The number of items to produce
+ * \param input The input vector to be filtered
+ * \param output The result of the filter operation
+ */
+ int filter(int nitems, const gr_complex *input, gr_complex *output);
+ };
+
+ } /* namespace kernel */
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_FFT_FILTER_H */
diff --git a/gr-filter/include/filter/fft_filter_ccc.h b/gr-filter/include/filter/fft_filter_ccc.h
new file mode 100644
index 0000000000..acec932775
--- /dev/null
+++ b/gr-filter/include/filter/fft_filter_ccc.h
@@ -0,0 +1,86 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_FILTER_FFT_FILTER_CCC_H
+#define INCLUDED_FILTER_FFT_FILTER_CCC_H
+
+#include <filter/api.h>
+#include <gr_sync_decimator.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API fft_filter_ccc : virtual public gr_sync_decimator
+ {
+ public:
+ // gr::filter::fft_filter_ccc::sptr
+ typedef boost::shared_ptr<fft_filter_ccc> sptr;
+
+ /*!
+ * \brief Fast FFT filter with gr_complex input, gr_complex output and gr_complex taps
+ * \ingroup filter_blk
+ *
+ * This block implements a complex decimating filter using the
+ * fast convolution method via an FFT. The decimation factor is
+ * an interger that is greater than or equal to 1.
+ *
+ * The filter takes a set of complex (or real) taps to use in
+ * the filtering operation. These taps can be defined as
+ * anything that satisfies the user's filtering needs. For
+ * standard filters such as lowpass, highpass, bandpass, etc.,
+ * the filter.firdes and filter.optfir classes provide
+ * convenient generating methods.
+ *
+ * This filter is implemented by using the FFTW package to
+ * perform the required FFTs. An optional argument, nthreads,
+ * may be passed to the constructor (or set using the
+ * set_nthreads member function) to split the FFT among N number
+ * of threads. This can improve performance on very large FFTs
+ * (that is, if the number of taps used is very large) if you
+ * have enough threads/cores to support it.
+ *
+ * \param decimation >= 1
+ * \param taps complex filter taps
+ * \param nthreads number of threads for the FFT to use
+ */
+ static sptr make(int decimation,
+ const std::vector<gr_complex> &taps,
+ int nthreads=1);
+
+ virtual void set_taps(const std::vector<gr_complex> &taps) = 0;
+ virtual std::vector<gr_complex> taps() const = 0;
+
+ /*!
+ * \brief Set number of threads to use.
+ */
+ virtual void set_nthreads(int n) = 0;
+
+ /*!
+ * \brief Get number of threads being used.
+ */
+ virtual int nthreads() const = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_FFT_FILTER_CCC_H */
diff --git a/gr-filter/include/filter/fft_filter_fff.h b/gr-filter/include/filter/fft_filter_fff.h
new file mode 100644
index 0000000000..d8140325f2
--- /dev/null
+++ b/gr-filter/include/filter/fft_filter_fff.h
@@ -0,0 +1,86 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_FILTER_FFT_FILTER_FFF_H
+#define INCLUDED_FILTER_FFT_FILTER_FFF_H
+
+#include <filter/api.h>
+#include <gr_sync_decimator.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API fft_filter_fff : virtual public gr_sync_decimator
+ {
+ public:
+ // gr::filter::fft_filter_fff::sptr
+ typedef boost::shared_ptr<fft_filter_fff> sptr;
+
+ /*!
+ * \brief Fast FFT filter with float input, float output and float taps
+ * \ingroup filter_blk
+ *
+ * This block implements a real-value decimating filter using
+ * the fast convolution method via an FFT. The decimation factor
+ * is an interger that is greater than or equal to 1.
+ *
+ * The filter takes a set of real-valued taps to use in
+ * the filtering operation. These taps can be defined as
+ * anything that satisfies the user's filtering needs. For
+ * standard filters such as lowpass, highpass, bandpass, etc.,
+ * the filter.firdes and filter.optfir classes provide
+ * convenient generating methods.
+ *
+ * This filter is implemented by using the FFTW package to
+ * perform the required FFTs. An optional argument, nthreads,
+ * may be passed to the constructor (or set using the
+ * set_nthreads member function) to split the FFT among N number
+ * of threads. This can improve performance on very large FFTs
+ * (that is, if the number of taps used is very large) if you
+ * have enough threads/cores to support it.
+ *
+ * \param decimation >= 1
+ * \param taps float filter taps
+ * \param nthreads number of threads for the FFT to use
+ */
+ static sptr make(int decimation,
+ const std::vector<float> &taps,
+ int nthreads=1);
+
+ virtual void set_taps(const std::vector<float> &taps) = 0;
+ virtual std::vector<float> taps() const = 0;
+
+ /*!
+ * \brief Set number of threads to use.
+ */
+ virtual void set_nthreads(int n) = 0;
+
+ /*!
+ * \brief Get number of threads being used.
+ */
+ virtual int nthreads() const = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_FFT_FILTER_FFF_H */
diff --git a/gr-filter/include/filter/filter_delay_fc.h b/gr-filter/include/filter/filter_delay_fc.h
new file mode 100644
index 0000000000..8a84a6a0e5
--- /dev/null
+++ b/gr-filter/include/filter/filter_delay_fc.h
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_FILTER_FILTER_DELAY_FC_H
+#define INCLUDED_FILTER_FILTER_DELAY_FC_H
+
+#include <filter/api.h>
+#include <gr_sync_block.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API filter_delay_fc : virtual public gr_sync_block
+ {
+ public:
+
+ // gr::filter::filter_delay_fc::sptr
+ typedef boost::shared_ptr<filter_delay_fc> sptr;
+
+ /*!
+ * \brief Filter-Delay Combination Block.
+ * \ingroup filter_blk
+ *
+ * The block takes one or two float stream and outputs a complex
+ * stream.
+ *
+ * If only one float stream is input, the real output is a
+ * delayed version of this input and the imaginary output is the
+ * filtered output.
+ *
+ * If two floats are connected to the input, then the real
+ * output is the delayed version of the first input, and the
+ * imaginary output is the filtered output.
+ *
+ * The delay in the real path accounts for the group delay
+ * introduced by the filter in the imaginary path. The filter
+ * taps needs to be calculated before initializing this block.
+ *
+ */
+ static sptr make(const std::vector<float> &taps);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_FILTER_DELAY_FC_H */
diff --git a/gr-filter/include/filter/fir_filter.h b/gr-filter/include/filter/fir_filter.h
new file mode 100644
index 0000000000..e861112681
--- /dev/null
+++ b/gr-filter/include/filter/fir_filter.h
@@ -0,0 +1,222 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_FILTER_FIR_FILTER_H
+#define INCLUDED_FILTER_FIR_FILTER_H
+
+#include <filter/api.h>
+#include <vector>
+#include <gr_complex.h>
+
+namespace gr {
+ namespace filter {
+ namespace kernel {
+
+ class FILTER_API fir_filter_fff
+ {
+ public:
+ fir_filter_fff(int decimation,
+ const std::vector<float> &taps);
+ ~fir_filter_fff();
+
+ void set_taps(const std::vector<float> &taps);
+ std::vector<float> taps() const;
+ unsigned int ntaps() const;
+
+ float filter(const float input[]);
+ void filterN(float output[],
+ const float input[],
+ unsigned long n);
+ void filterNdec(float output[],
+ const float input[],
+ unsigned long n,
+ unsigned int decimate);
+
+ protected:
+ std::vector<float> d_taps;
+ unsigned int d_ntaps;
+ float **d_aligned_taps;
+ float *d_output;
+ int d_align;
+ int d_naligned;
+ };
+
+ /**************************************************************/
+
+ class FILTER_API fir_filter_ccf
+ {
+ public:
+ fir_filter_ccf(int decimation,
+ const std::vector<float> &taps);
+ ~fir_filter_ccf();
+
+ void set_taps(const std::vector<float> &taps);
+ std::vector<float> taps() const;
+ unsigned int ntaps() const;
+
+ gr_complex filter(const gr_complex input[]);
+ void filterN(gr_complex output[],
+ const gr_complex input[],
+ unsigned long n);
+ void filterNdec(gr_complex output[],
+ const gr_complex input[],
+ unsigned long n,
+ unsigned int decimate);
+
+ protected:
+ std::vector<float> d_taps;
+ unsigned int d_ntaps;
+ float **d_aligned_taps;
+ gr_complex *d_output;
+ int d_align;
+ int d_naligned;
+ };
+
+ /**************************************************************/
+
+ class FILTER_API fir_filter_fcc
+ {
+ public:
+ fir_filter_fcc(int decimation,
+ const std::vector<gr_complex> &taps);
+ ~fir_filter_fcc();
+
+ void set_taps(const std::vector<gr_complex> &taps);
+ std::vector<gr_complex> taps() const;
+ unsigned int ntaps() const;
+
+ gr_complex filter(const float input[]);
+ void filterN(gr_complex output[],
+ const float input[],
+ unsigned long n);
+ void filterNdec(gr_complex output[],
+ const float input[],
+ unsigned long n,
+ unsigned int decimate);
+
+ protected:
+ std::vector<gr_complex> d_taps;
+ unsigned int d_ntaps;
+ gr_complex **d_aligned_taps;
+ gr_complex *d_output;
+ int d_align;
+ int d_naligned;
+ };
+
+ /**************************************************************/
+
+ class FILTER_API fir_filter_ccc
+ {
+ public:
+ fir_filter_ccc(int decimation,
+ const std::vector<gr_complex> &taps);
+ ~fir_filter_ccc();
+
+ void set_taps(const std::vector<gr_complex> &taps);
+ std::vector<gr_complex> taps() const;
+ unsigned int ntaps() const;
+
+ gr_complex filter(const gr_complex input[]);
+ void filterN(gr_complex output[],
+ const gr_complex input[],
+ unsigned long n);
+ void filterNdec(gr_complex output[],
+ const gr_complex input[],
+ unsigned long n,
+ unsigned int decimate);
+
+ protected:
+ std::vector<gr_complex> d_taps;
+ unsigned int d_ntaps;
+ gr_complex **d_aligned_taps;
+ gr_complex *d_output;
+ int d_align;
+ int d_naligned;
+ };
+
+ /**************************************************************/
+
+ class FILTER_API fir_filter_scc
+ {
+ public:
+ fir_filter_scc(int decimation,
+ const std::vector<gr_complex> &taps);
+ ~fir_filter_scc();
+
+ void set_taps(const std::vector<gr_complex> &taps);
+ std::vector<gr_complex> taps() const;
+ unsigned int ntaps() const;
+
+ gr_complex filter(const short input[]);
+ void filterN(gr_complex output[],
+ const short input[],
+ unsigned long n);
+ void filterNdec(gr_complex output[],
+ const short input[],
+ unsigned long n,
+ unsigned int decimate);
+
+ protected:
+ std::vector<gr_complex> d_taps;
+ unsigned int d_ntaps;
+ gr_complex **d_aligned_taps;
+ gr_complex *d_output;
+ int d_align;
+ int d_naligned;
+ };
+
+ /**************************************************************/
+
+ class FILTER_API fir_filter_fsf
+ {
+ public:
+ fir_filter_fsf(int decimation,
+ const std::vector<float> &taps);
+ ~fir_filter_fsf();
+
+ void set_taps(const std::vector<float> &taps);
+ std::vector<float> taps() const;
+ unsigned int ntaps() const;
+
+ short filter(const float input[]);
+ void filterN(short output[],
+ const float input[],
+ unsigned long n);
+ void filterNdec(short output[],
+ const float input[],
+ unsigned long n,
+ unsigned int decimate);
+
+ protected:
+ std::vector<float> d_taps;
+ unsigned int d_ntaps;
+ float **d_aligned_taps;
+ short *d_output;
+ int d_align;
+ int d_naligned;
+ };
+
+ } /* namespace kernel */
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_FIR_FILTER_H */
diff --git a/gr-filter/include/filter/fir_filter_XXX.h.t b/gr-filter/include/filter/fir_filter_XXX.h.t
new file mode 100644
index 0000000000..98e82f510d
--- /dev/null
+++ b/gr-filter/include/filter/fir_filter_XXX.h.t
@@ -0,0 +1,82 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/* @WARNING@ */
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <filter/api.h>
+#include <gr_sync_decimator.h>
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \brief FIR filter with @I_TYPE@ input, @O_TYPE@ output, and @TAP_TYPE@ taps
+ * \ingroup filter_blk
+ *
+ * The fir_filter_XXX blocks create finite impulse response
+ * (FIR) filters that perform the convolution in the time
+ * domain:
+ *
+ * \code
+ * out = 0
+ * for i in ntaps:
+ * out += input[n-i] * taps[i]
+ * \endcode
+ *
+ * The taps are a C++ vector (or Python list) of values of the
+ * type specified by the third letter in the block's suffix. For
+ * this block, the value is of type @TAP_TYPE@. Taps can be
+ * created using the firdes or optfir tools.
+ *
+ * These versions of the filter can also act as down-samplers
+ * (or decimators) by specifying an integer value for \p
+ * decimation.
+ *
+ */
+ class FILTER_API @BASE_NAME@ : virtual public gr_sync_decimator
+ {
+ public:
+
+ // gr::filter::@BASE_NAME@::sptr
+ typedef boost::shared_ptr<@BASE_NAME@> sptr;
+
+ /*!
+ * \brief FIR filter with @I_TYPE@ input, @O_TYPE@ output, and @TAP_TYPE@ taps
+ * \ingroup filter_blk
+ *
+ * \param decimation set the integer decimation rate
+ * \param taps a vector/list of taps of type @TAP_TYPE@
+ */
+ static sptr make(int decimation,
+ const std::vector<@TAP_TYPE@> &taps);
+
+ virtual void set_taps(const std::vector<@TAP_TYPE@> &taps) = 0;
+ virtual std::vector<@TAP_TYPE@> taps() const = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* @GUARD_NAME@ */
diff --git a/gr-filter/include/filter/fir_filter_with_buffer.h b/gr-filter/include/filter/fir_filter_with_buffer.h
new file mode 100644
index 0000000000..007eae3fa6
--- /dev/null
+++ b/gr-filter/include/filter/fir_filter_with_buffer.h
@@ -0,0 +1,326 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_FILTER_FIR_FILTER_WITH_BUFFER_H
+#define INCLUDED_FILTER_FIR_FILTER_WITH_BUFFER_H
+
+#include <filter/api.h>
+#include <vector>
+#include <gr_complex.h>
+
+namespace gr {
+ namespace filter {
+ namespace kernel {
+
+ /*!
+ * \brief FIR with internal buffer for float input, float output and float taps.
+ * \ingroup filter
+ */
+ class FILTER_API fir_filter_with_buffer_fff
+ {
+ private:
+ std::vector<float> d_taps;
+ unsigned int d_ntaps;
+ float *d_buffer_ptr;
+ float *d_buffer;
+ unsigned int d_idx;
+ float **d_aligned_taps;
+ float *d_output;
+ int d_align;
+ int d_naligned;
+
+ 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_filter_with_buffer_fff(const std::vector<float> &taps);
+
+ ~fir_filter_with_buffer_fff();
+
+ // MANIPULATORS
+
+ /*!
+ * \brief compute a single output value.
+ *
+ * \p input is a single input value of the filter type
+ *
+ * \returns the filtered input value.
+ */
+ float filter(float input);
+
+ /*!
+ * \brief compute a single output value; designed for decimating filters.
+ *
+ * \p input is a single input value of the filter type. The value of dec is the
+ * decimating value of the filter, so input[] must have dec valid values.
+ * The filter pushes dec number of items onto the circ. buffer before computing
+ * a single output.
+ *
+ * \returns the filtered input value.
+ */
+ float filter(const float input[], unsigned long dec);
+
+ /*!
+ * \brief compute an array of N output values.
+ *
+ * \p input must have (n - 1 + ntaps()) valid entries.
+ * input[0] .. input[n - 1 + ntaps() - 1] are referenced to compute the output values.
+ */
+ void filterN(float output[],
+ const float input[],
+ unsigned long n);
+
+ /*!
+ * \brief compute an array of N output values, decimating the input
+ *
+ * \p input must have (decimate * (n - 1) + ntaps()) valid entries.
+ * input[0] .. input[decimate * (n - 1) + ntaps() - 1] are referenced to
+ * compute the output values.
+ */
+ void filterNdec(float output[], const float input[],
+ unsigned long n, unsigned long decimate);
+
+ // ACCESSORS
+
+ /*!
+ * \return number of taps in filter.
+ */
+ unsigned int ntaps() const { return d_ntaps; }
+
+ /*!
+ * \brief install \p new_taps as the current taps.
+ */
+ void set_taps(const std::vector<float> &taps);
+
+ /*!
+ * \return current taps
+ */
+ std::vector<float> taps() const;
+ };
+
+
+ /**************************************************************/
+
+
+ /*!
+ * \brief FIR with internal buffer for gr_complex input, gr_complex output and gr_complex taps.
+ * \ingroup filter
+ */
+ class FILTER_API fir_filter_with_buffer_ccc
+ {
+ private:
+ std::vector<gr_complex> d_taps;
+ unsigned int d_ntaps;
+ gr_complex *d_buffer_ptr;
+ gr_complex *d_buffer;
+ unsigned int d_idx;
+ gr_complex **d_aligned_taps;
+ gr_complex *d_output;
+ int d_align;
+ int d_naligned;
+
+ 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_filter_with_buffer_ccc(const std::vector<gr_complex> &taps);
+
+ ~fir_filter_with_buffer_ccc();
+
+ // MANIPULATORS
+
+ /*!
+ * \brief compute a single output value.
+ *
+ * \p input is a single input value of the filter type
+ *
+ * \returns the filtered input value.
+ */
+ gr_complex filter(gr_complex input);
+
+ /*!
+ * \brief compute a single output value; designed for decimating filters.
+ *
+ * \p input is a single input value of the filter type. The value of dec is the
+ * decimating value of the filter, so input[] must have dec valid values.
+ * The filter pushes dec number of items onto the circ. buffer before computing
+ * a single output.
+ *
+ * \returns the filtered input value.
+ */
+ gr_complex filter(const gr_complex input[], unsigned long dec);
+
+ /*!
+ * \brief compute an array of N output values.
+ *
+ * \p input must have (n - 1 + ntaps()) valid entries.
+ * input[0] .. input[n - 1 + ntaps() - 1] are referenced to compute the output values.
+ */
+ void filterN(gr_complex output[],
+ const gr_complex input[],
+ unsigned long n);
+
+ /*!
+ * \brief compute an array of N output values, decimating the input
+ *
+ * \p input must have (decimate * (n - 1) + ntaps()) valid entries.
+ * input[0] .. input[decimate * (n - 1) + ntaps() - 1] are referenced to
+ * compute the output values.
+ */
+ void filterNdec(gr_complex output[], const gr_complex input[],
+ unsigned long n, unsigned long decimate);
+
+ // ACCESSORS
+
+ /*!
+ * \return number of taps in filter.
+ */
+ unsigned int ntaps() const { return d_ntaps; }
+
+ /*!
+ * \brief install \p new_taps as the current taps.
+ */
+ void set_taps(const std::vector<gr_complex> &taps);
+
+ /*!
+ * \return current taps
+ */
+ std::vector<gr_complex> taps() const;
+ };
+
+
+ /**************************************************************/
+
+
+ /*!
+ * \brief FIR with internal buffer for gr_complex input, gr_complex output and gr_complex taps.
+ * \ingroup filter
+ */
+ class FILTER_API fir_filter_with_buffer_ccf
+ {
+ private:
+ std::vector<float> d_taps;
+ unsigned int d_ntaps;
+ gr_complex *d_buffer_ptr;
+ gr_complex *d_buffer;
+ unsigned int d_idx;
+ float **d_aligned_taps;
+ gr_complex *d_output;
+ int d_align;
+ int d_naligned;
+
+ 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_filter_with_buffer_ccf(const std::vector<float> &taps);
+
+ ~fir_filter_with_buffer_ccf();
+
+ // MANIPULATORS
+
+ /*!
+ * \brief compute a single output value.
+ *
+ * \p input is a single input value of the filter type
+ *
+ * \returns the filtered input value.
+ */
+ gr_complex filter(gr_complex input);
+
+ /*!
+ * \brief compute a single output value; designed for decimating filters.
+ *
+ * \p input is a single input value of the filter type. The value of dec is the
+ * decimating value of the filter, so input[] must have dec valid values.
+ * The filter pushes dec number of items onto the circ. buffer before computing
+ * a single output.
+ *
+ * \returns the filtered input value.
+ */
+ gr_complex filter(const gr_complex input[], unsigned long dec);
+
+ /*!
+ * \brief compute an array of N output values.
+ *
+ * \p input must have (n - 1 + ntaps()) valid entries.
+ * input[0] .. input[n - 1 + ntaps() - 1] are referenced to compute the output values.
+ */
+ void filterN(gr_complex output[],
+ const gr_complex input[],
+ unsigned long n);
+
+ /*!
+ * \brief compute an array of N output values, decimating the input
+ *
+ * \p input must have (decimate * (n - 1) + ntaps()) valid entries.
+ * input[0] .. input[decimate * (n - 1) + ntaps() - 1] are referenced to
+ * compute the output values.
+ */
+ void filterNdec(gr_complex output[], const gr_complex input[],
+ unsigned long n, unsigned long decimate);
+
+ // ACCESSORS
+
+ /*!
+ * \return number of taps in filter.
+ */
+ unsigned int ntaps() const { return d_ntaps; }
+
+ /*!
+ * \brief install \p new_taps as the current taps.
+ */
+ void set_taps(const std::vector<float> &taps);
+
+ /*!
+ * \return current taps
+ */
+ std::vector<float> taps() const;
+ };
+
+
+ } /* namespace kernel */
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_FIR_FILTER_WITH_BUFFER_H */
diff --git a/gr-filter/include/filter/firdes.h b/gr-filter/include/filter/firdes.h
new file mode 100644
index 0000000000..172563ea00
--- /dev/null
+++ b/gr-filter/include/filter/firdes.h
@@ -0,0 +1,378 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2008,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _FILTER_FIRDES_H_
+#define _FILTER_FIRDES_H_
+
+#include <filter/api.h>
+#include <vector>
+#include <cmath>
+#include <gr_complex.h>
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \brief Finite Impulse Response (FIR) filter design functions.
+ * \ingroup filter_design
+ */
+
+ class FILTER_API firdes {
+ public:
+
+ enum win_type {
+ WIN_HAMMING = 0, // max attenuation 53 dB
+ WIN_HANN = 1, // max attenuation 44 dB
+ WIN_BLACKMAN = 2, // max attenuation 74 dB
+ WIN_RECTANGULAR = 3,
+ WIN_KAISER = 4, // max attenuation a function of beta, google it
+ WIN_BLACKMAN_hARRIS = 5,
+ WIN_BLACKMAN_HARRIS = 5, // alias for capitalization consistency
+ };
+
+
+ // ... class methods ...
+
+ /*!
+ * \brief use "window method" to design a low-pass FIR filter
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p sampling_freq: sampling freq (Hz)
+ * \p cutoff_freq: center of transition band (Hz)
+ * \p transition_width: width of transition band (Hz).
+ * The normalized width of the transition
+ * band is what sets the number of taps
+ * required. Narrow --> more taps
+ * \p window_type: What kind of window to use. Determines
+ * maximum attenuation and passband ripple.
+ * \p beta: parameter for Kaiser window
+ */
+ static std::vector<float>
+ low_pass(double gain,
+ double sampling_freq,
+ double cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ win_type window = WIN_HAMMING,
+ double beta = 6.76); // used only with Kaiser
+
+ /*!
+ * \brief use "window method" to design a low-pass FIR filter
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p sampling_freq: sampling freq (Hz)
+ * \p cutoff_freq: center of transition band (Hz)
+ * \p transition_width: width of transition band (Hz).
+ * \p attenuation_dB required stopband attenuation
+ * The normalized width of the transition
+ * band and the required stop band
+ * attenuation is what sets the number of taps
+ * required. Narrow --> more taps
+ * More attenuatin --> more taps
+ * \p window_type: What kind of window to use. Determines
+ * maximum attenuation and passband ripple.
+ * \p beta: parameter for Kaiser window
+ */
+
+ static std::vector<float>
+ low_pass_2(double gain,
+ double sampling_freq,
+ double cutoff_freq, // Hz beginning transition band
+ double transition_width, // Hz width of transition band
+ double attenuation_dB, // out of band attenuation dB
+ win_type window = WIN_HAMMING,
+ double beta = 6.76); // used only with Kaiser
+
+ /*!
+ * \brief use "window method" to design a high-pass FIR filter
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p sampling_freq: sampling freq (Hz)
+ * \p cutoff_freq: center of transition band (Hz)
+ * \p transition_width: width of transition band (Hz).
+ * The normalized width of the transition
+ * band is what sets the number of taps
+ * required. Narrow --> more taps
+ * \p window_type: What kind of window to use. Determines
+ * maximum attenuation and passband ripple.
+ * \p beta: parameter for Kaiser window
+ */
+
+ static std::vector<float>
+ high_pass(double gain,
+ double sampling_freq,
+ double cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ win_type window = WIN_HAMMING,
+ double beta = 6.76); // used only with Kaiser
+
+ /*!
+ * \brief use "window method" to design a high-pass FIR filter
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p sampling_freq: sampling freq (Hz)
+ * \p cutoff_freq: center of transition band (Hz)
+ * \p transition_width: width of transition band (Hz).
+ * \p attenuation_dB out of band attenuation
+ * The normalized width of the transition
+ * band and the required stop band
+ * attenuation is what sets the number of taps
+ * required. Narrow --> more taps
+ * More attenuation --> more taps
+ * \p window_type: What kind of window to use. Determines
+ * maximum attenuation and passband ripple.
+ * \p beta: parameter for Kaiser window
+ */
+
+ static std::vector<float>
+ high_pass_2(double gain,
+ double sampling_freq,
+ double cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ double attenuation_dB, // out of band attenuation dB
+ win_type window = WIN_HAMMING,
+ double beta = 6.76); // used only with Kaiser
+
+ /*!
+ * \brief use "window method" to design a band-pass FIR filter
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p sampling_freq: sampling freq (Hz)
+ * \p low_cutoff_freq: center of transition band (Hz)
+ * \p high_cutoff_freq: center of transition band (Hz)
+ * \p transition_width: width of transition band (Hz).
+ * The normalized width of the transition
+ * band is what sets the number of taps
+ * required. Narrow --> more taps
+ * \p window_type: What kind of window to use. Determines
+ * maximum attenuation and passband ripple.
+ * \p beta: parameter for Kaiser window
+ */
+ static std::vector<float>
+ band_pass(double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz center of transition band
+ double high_cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ win_type window = WIN_HAMMING,
+ double beta = 6.76); // used only with Kaiser
+
+ /*!
+ * \brief use "window method" to design a band-pass FIR filter
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p sampling_freq: sampling freq (Hz)
+ * \p low_cutoff_freq: center of transition band (Hz)
+ * \p high_cutoff_freq: center of transition band (Hz)
+ * \p transition_width: width of transition band (Hz).
+ * \p attenuation_dB out of band attenuation
+ * The normalized width of the transition
+ * band and the required stop band
+ * attenuation is what sets the number of taps
+ * required. Narrow --> more taps
+ * More attenuation --> more taps
+ * \p window_type: What kind of window to use. Determines
+ * maximum attenuation and passband ripple.
+ * \p beta: parameter for Kaiser window
+ */
+
+ static std::vector<float>
+ band_pass_2(double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz beginning transition band
+ double high_cutoff_freq, // Hz beginning transition band
+ double transition_width, // Hz width of transition band
+ double attenuation_dB, // out of band attenuation dB
+ win_type window = WIN_HAMMING,
+ double beta = 6.76); // used only with Kaiser
+
+ /*!
+ * \brief use "window method" to design a complex band-pass FIR filter
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p sampling_freq: sampling freq (Hz)
+ * \p low_cutoff_freq: center of transition band (Hz)
+ * \p high_cutoff_freq: center of transition band (Hz)
+ * \p transition_width: width of transition band (Hz).
+ * The normalized width of the transition
+ * band is what sets the number of taps
+ * required. Narrow --> more taps
+ * \p window_type: What kind of window to use. Determines
+ * maximum attenuation and passband ripple.
+ * \p beta: parameter for Kaiser window
+ */
+ static std::vector<gr_complex>
+ complex_band_pass(double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz center of transition band
+ double high_cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ win_type window = WIN_HAMMING,
+ double beta = 6.76); // used only with Kaiser
+
+ /*!
+ * \brief use "window method" to design a complex band-pass FIR filter
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p sampling_freq: sampling freq (Hz)
+ * \p low_cutoff_freq: center of transition band (Hz)
+ * \p high_cutoff_freq: center of transition band (Hz)
+ * \p transition_width: width of transition band (Hz).
+ * \p attenuation_dB out of band attenuation
+ * The normalized width of the transition
+ * band and the required stop band
+ * attenuation is what sets the number of taps
+ * required. Narrow --> more taps
+ * More attenuation --> more taps
+ * \p window_type: What kind of window to use. Determines
+ * maximum attenuation and passband ripple.
+ * \p beta: parameter for Kaiser window
+ */
+
+ static std::vector<gr_complex>
+ complex_band_pass_2(double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz beginning transition band
+ double high_cutoff_freq, // Hz beginning transition band
+ double transition_width, // Hz width of transition band
+ double attenuation_dB, // out of band attenuation dB
+ win_type window = WIN_HAMMING,
+ double beta = 6.76); // used only with Kaiser
+
+ /*!
+ * \brief use "window method" to design a band-reject FIR filter
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p sampling_freq: sampling freq (Hz)
+ * \p low_cutoff_freq: center of transition band (Hz)
+ * \p high_cutoff_freq: center of transition band (Hz)
+ * \p transition_width: width of transition band (Hz).
+ * The normalized width of the transition
+ * band is what sets the number of taps
+ * required. Narrow --> more taps
+ * \p window_type: What kind of window to use. Determines
+ * maximum attenuation and passband ripple.
+ * \p beta: parameter for Kaiser window
+ */
+
+ static std::vector<float>
+ band_reject(double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz center of transition band
+ double high_cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ win_type window = WIN_HAMMING,
+ double beta = 6.76); // used only with Kaiser
+
+ /*!
+ * \brief use "window method" to design a band-reject FIR filter
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p sampling_freq: sampling freq (Hz)
+ * \p low_cutoff_freq: center of transition band (Hz)
+ * \p high_cutoff_freq: center of transition band (Hz)
+ * \p transition_width: width of transition band (Hz).
+ * \p attenuation_dB out of band attenuation
+ * The normalized width of the transition
+ * band and the required stop band
+ * attenuation is what sets the number of taps
+ * required. Narrow --> more taps
+ * More attenuation --> more taps
+ * \p window_type: What kind of window to use. Determines
+ * maximum attenuation and passband ripple.
+ * \p beta: parameter for Kaiser window
+ */
+
+ static std::vector<float>
+ band_reject_2(double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz beginning transition band
+ double high_cutoff_freq, // Hz beginning transition band
+ double transition_width, // Hz width of transition band
+ double attenuation_dB, // out of band attenuation dB
+ win_type window = WIN_HAMMING,
+ double beta = 6.76); // used only with Kaiser
+
+ /*!\brief design a Hilbert Transform Filter
+ *
+ * \p ntaps: Number of taps, must be odd
+ * \p window_type: What kind of window to use
+ * \p beta: Only used for Kaiser
+ */
+ static std::vector<float>
+ hilbert(unsigned int ntaps = 19,
+ win_type windowtype = WIN_RECTANGULAR,
+ double beta = 6.76);
+
+ /*!
+ * \brief design a Root Cosine FIR Filter (do we need a window?)
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p sampling_freq: sampling freq (Hz)
+ * \p symbol rate: symbol rate, must be a factor of sample rate
+ * \p alpha: excess bandwidth factor
+ * \p ntaps: number of taps
+ */
+ static std::vector<float>
+ root_raised_cosine(double gain,
+ double sampling_freq,
+ double symbol_rate, // Symbol rate, NOT bitrate (unless BPSK)
+ double alpha, // Excess Bandwidth Factor
+ int ntaps);
+
+ /*!
+ * \brief design a Gaussian filter
+ *
+ * \p gain: overall gain of filter (typically 1.0)
+ * \p symbols per bit: symbol rate, must be a factor of sample rate
+ * \p ntaps: number of taps
+ */
+ static std::vector<float>
+ gaussian(double gain,
+ double spb,
+ double bt, // Bandwidth to bitrate ratio
+ int ntaps);
+
+ // window functions ...
+ static std::vector<float> window (win_type type, int ntaps, double beta);
+
+ private:
+ static double bessi0(double x);
+ static void sanity_check_1f(double sampling_freq, double f1,
+ double transition_width);
+ static void sanity_check_2f(double sampling_freq, double f1, double f2,
+ double transition_width);
+ static void sanity_check_2f_c(double sampling_freq, double f1, double f2,
+ double transition_width);
+
+ static int compute_ntaps(double sampling_freq,
+ double transition_width,
+ win_type window_type, double beta);
+
+ static int compute_ntaps_windes(double sampling_freq,
+ double transition_width,
+ double attenuation_dB);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* _FILTER_FIRDES_H_ */
diff --git a/gr-filter/include/filter/fractional_interpolator_cc.h b/gr-filter/include/filter/fractional_interpolator_cc.h
new file mode 100644
index 0000000000..bb0e18932e
--- /dev/null
+++ b/gr-filter/include/filter/fractional_interpolator_cc.h
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_FRACTIONAL_INTERPOLATOR_CC_H
+#define INCLUDED_FRACTIONAL_INTERPOLATOR_CC_H
+
+#include <filter/api.h>
+#include <gr_block.h>
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \brief Interpolating MMSE filter with complex input, complex output
+ * \ingroup filter_blk
+ */
+ class FILTER_API fractional_interpolator_cc : virtual public gr_block
+ {
+ public:
+ // gr::filter::fractional_interpolator_cc::sptr
+ typedef boost::shared_ptr<fractional_interpolator_cc> sptr;
+
+ /*!
+ * \brief Build the interpolating MMSE filter (complex input, complex output)
+ *
+ * \param phase_shift The phase shift of the output signal to the input
+ * \param interp_ratio The interpolation ratio = input_rate / output_rate.
+ */
+ static sptr make(float phase_shift,
+ float interp_ratio);
+
+ virtual float mu() const = 0;
+ virtual float interp_ratio() const = 0;
+ virtual void set_mu (float mu) = 0;
+ virtual void set_interp_ratio(float interp_ratio) = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FRACTIONAL_INTERPOLATOR_FF_H */
diff --git a/gr-filter/include/filter/fractional_interpolator_ff.h b/gr-filter/include/filter/fractional_interpolator_ff.h
new file mode 100644
index 0000000000..fc43c34570
--- /dev/null
+++ b/gr-filter/include/filter/fractional_interpolator_ff.h
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_FRACTIONAL_INTERPOLATOR_FF_H
+#define INCLUDED_FRACTIONAL_INTERPOLATOR_FF_H
+
+#include <filter/api.h>
+#include <gr_block.h>
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \brief Interpolating MMSE filter with float input, float output
+ * \ingroup filter_blk
+ */
+ class FILTER_API fractional_interpolator_ff : virtual public gr_block
+ {
+ public:
+ // gr::filter::fractional_interpolator_ff::sptr
+ typedef boost::shared_ptr<fractional_interpolator_ff> sptr;
+
+ /*!
+ * \brief Build the interpolating MMSE filter (float input, float output)
+ *
+ * \param phase_shift The phase shift of the output signal to the input
+ * \param interp_ratio The interpolation ratio = input_rate / output_rate.
+ */
+ static sptr make(float phase_shift,
+ float interp_ratio);
+
+ virtual float mu() const = 0;
+ virtual float interp_ratio() const = 0;
+ virtual void set_mu (float mu) = 0;
+ virtual void set_interp_ratio(float interp_ratio) = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FRACTIONAL_INTERPOLATOR_FF_H */
diff --git a/gr-filter/include/filter/freq_xlating_fir_filter_XXX.h.t b/gr-filter/include/filter/freq_xlating_fir_filter_XXX.h.t
new file mode 100644
index 0000000000..88e15f823d
--- /dev/null
+++ b/gr-filter/include/filter/freq_xlating_fir_filter_XXX.h.t
@@ -0,0 +1,90 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2004,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * WARNING: This file is automatically generated by cmake.
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <filter/api.h>
+#include <gr_sync_decimator.h>
+#include <gr_rotator.h>
+
+namespace gr {
+ namespace filter {
+
+
+ /*!
+ * \brief FIR filter combined with frequency translation with
+ * @I_TYPE@ input, @O_TYPE@ output and @TAP_TYPE@ taps
+ *
+ * \ingroup filter_blk
+ *
+ * This class efficiently combines a frequency translation
+ * (typically "down conversion") with a FIR filter (typically
+ * low-pass) and decimation. It is ideally suited for a "channel
+ * selection filter" and can be efficiently used to select and
+ * decimate a narrow band signal out of wide bandwidth input.
+ *
+ * Uses a single input array to produce a single output array.
+ * Additional inputs and/or outputs are ignored.
+ */
+ class FILTER_API @BASE_NAME@ : virtual public gr_sync_decimator
+ {
+ public:
+ // gr::filter::@BASE_NAME@::sptr
+ typedef boost::shared_ptr<@BASE_NAME@> sptr;
+
+ /*!
+ * \brief FIR filter with @I_TYPE@ input, @O_TYPE@ output, and
+ * @TAP_TYPE@ taps that also frequency translates a signal from
+ * \p center_freq.
+ *
+ * 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.
+ *
+ * \param decimation set the integer decimation rate
+ * \param taps a vector/list of taps of type @TAP_TYPE@
+ * \param center_freq Center frequency of signal to down convert from (Hz)
+ * \param sampling_freq Sampling rate of signal (in Hz)
+ */
+ static sptr make(int decimation,
+ const std::vector<@TAP_TYPE@> &taps,
+ double center_freq,
+ double sampling_freq);
+
+ virtual void set_center_freq(double center_freq) = 0;
+ virtual double center_freq() const = 0;
+
+ virtual void set_taps(const std::vector<@TAP_TYPE@> &taps) = 0;
+ virtual std::vector<@TAP_TYPE@> taps() const = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* @GUARD_NAME@ */
diff --git a/gnuradio-core/src/lib/general/gr_map_bb.h b/gr-filter/include/filter/hilbert_fc.h
index 0a2f5a45f8..de7cd82b69 100644
--- a/gnuradio-core/src/lib/general/gr_map_bb.h
+++ b/gr-filter/include/filter/hilbert_fc.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2004,2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -19,34 +19,35 @@
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
-#ifndef INCLUDED_GR_MAP_BB_H
-#define INCLUDED_GR_MAP_BB_H
-#include <gr_core_api.h>
-#include <gr_sync_block.h>
-
-class gr_map_bb;
-typedef boost::shared_ptr<gr_map_bb> gr_map_bb_sptr;
-
-GR_CORE_API gr_map_bb_sptr gr_make_map_bb(const std::vector<int> &map);
-
-/*!
- * \brief output[i] = map[input[i]]
- * \ingroup coding_blk
- */
+#ifndef INCLUDED_FILTER_HILBERT_FC_H
+#define INCLUDED_FILTER_HILBERT_FC_H
-class GR_CORE_API gr_map_bb : public gr_sync_block
-{
- friend GR_CORE_API gr_map_bb_sptr gr_make_map_bb(const std::vector<int> &map);
-
- unsigned char d_map[0x100];
-
- gr_map_bb(const std::vector<int> &map);
-
-public:
- int work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-};
-
-#endif /* INCLUDED_GR_MAP_BB_H */
+#include <filter/api.h>
+#include <gr_sync_block.h>
+#include <gr_types.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API hilbert_fc : virtual public gr_sync_block
+ {
+ public:
+ // gr::filter::hilbert_fc::sptr
+ typedef boost::shared_ptr<hilbert_fc> sptr;
+
+ /*!
+ * \brief Hilbert transformer.
+ * \ingroup filter_blk
+ *
+ * real output is input appropriately delayed.
+ * imaginary output is hilbert filtered (90 degree phase shift)
+ * version of input.
+ */
+ static sptr make(unsigned int ntaps);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_HILBERT_FC_H */
diff --git a/gr-filter/include/filter/iir_filter.h b/gr-filter/include/filter/iir_filter.h
new file mode 100644
index 0000000000..667acec358
--- /dev/null
+++ b/gr-filter/include/filter/iir_filter.h
@@ -0,0 +1,183 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_IIR_FILTER_H
+#define INCLUDED_IIR_FILTER_H
+
+#include <filter/api.h>
+#include <vector>
+#include <stdexcept>
+
+namespace gr {
+ namespace filter {
+ namespace kernel {
+
+ /*!
+ * \brief base class template for Infinite Impulse Response filter (IIR)
+ */
+ template<class i_type, class o_type, class tap_type>
+ class iir_filter
+ {
+ public:
+ /*!
+ * \brief Construct an IIR with the given taps.
+ *
+ * This filter uses the Direct Form I implementation, where
+ * \p fftaps contains the feed-forward taps, and \p fbtaps the feedback ones.
+ *
+ * \p fftaps and \p fbtaps must have equal numbers of taps
+ *
+ * The input and output satisfy a difference equation of the form
+
+ \f[
+ y[n] - \sum_{k=1}^{M} a_k y[n-k] = \sum_{k=0}^{N} b_k x[n-k]
+ \f]
+
+ * with the corresponding rational system function
+
+ \f[
+ H(z) = \frac{\sum_{k=0}^{N} b_k z^{-k}}{1 - \sum_{k=1}^{M} a_k z^{-k}}
+ \f]
+
+ * Note that some texts define the system function with a + in
+ * the denominator. If you're using that convention, you'll
+ * need to negate the feedback taps.
+ */
+ iir_filter(const std::vector<tap_type>& fftaps,
+ const std::vector<tap_type>& fbtaps) throw (std::invalid_argument)
+ {
+ set_taps(fftaps, fbtaps);
+ }
+
+ iir_filter() : d_latest_n(0),d_latest_m(0) { }
+
+ ~iir_filter() {}
+
+ /*!
+ * \brief compute a single output value.
+ * \returns the filtered input value.
+ */
+ o_type filter(const i_type input);
+
+ /*!
+ * \brief compute an array of N output values.
+ * \p input must have N valid entries.
+ */
+ void filter_n(o_type output[], const i_type input[], long n);
+
+ /*!
+ * \return number of taps in filter.
+ */
+ unsigned ntaps_ff() const { return d_fftaps.size(); }
+ unsigned ntaps_fb() const { return d_fbtaps.size(); }
+
+ /*!
+ * \brief install new taps.
+ */
+ void set_taps(const std::vector<tap_type> &fftaps,
+ const std::vector<tap_type> &fbtaps) throw (std::invalid_argument)
+ {
+ d_latest_n = 0;
+ d_latest_m = 0;
+ d_fftaps = fftaps;
+ d_fbtaps = fbtaps;
+
+ int n = fftaps.size();
+ int m = fbtaps.size();
+ d_prev_input.resize(2 * n);
+ d_prev_output.resize(2 * m);
+
+ for(int i = 0; i < 2 * n; i++) {
+ d_prev_input[i] = 0;
+ }
+ for(int i = 0; i < 2 * m; i++) {
+ d_prev_output[i] = 0;
+ }
+ }
+
+ protected:
+ std::vector<tap_type> d_fftaps;
+ std::vector<tap_type> d_fbtaps;
+ int d_latest_n;
+ int d_latest_m;
+ std::vector<tap_type> d_prev_output;
+ std::vector<i_type> d_prev_input;
+ };
+
+ //
+ // general case. We may want to specialize this
+ //
+ template<class i_type, class o_type, class tap_type>
+ o_type
+ iir_filter<i_type, o_type, tap_type>::filter(const i_type input)
+ {
+ tap_type acc;
+ unsigned i = 0;
+ unsigned n = ntaps_ff();
+ unsigned m = ntaps_fb();
+
+ if(n == 0)
+ return (o_type)0;
+
+ int latest_n = d_latest_n;
+ int latest_m = d_latest_m;
+
+ acc = d_fftaps[0] * input;
+ for(i = 1; i < n; i ++)
+ acc += (d_fftaps[i] * d_prev_input[latest_n + i]);
+ for(i = 1; i < m; i ++)
+ acc += (d_fbtaps[i] * d_prev_output[latest_m + i]);
+
+ // store the values twice to avoid having to handle wrap-around in the loop
+ d_prev_output[latest_m] = acc;
+ d_prev_output[latest_m+m] = acc;
+ d_prev_input[latest_n] = input;
+ d_prev_input[latest_n+n] = input;
+
+ latest_n--;
+ latest_m--;
+ if(latest_n < 0)
+ latest_n += n;
+ if(latest_m < 0)
+ latest_m += m;
+
+ d_latest_m = latest_m;
+ d_latest_n = latest_n;
+ return (o_type)acc;
+ }
+
+ template<class i_type, class o_type, class tap_type>
+ void
+ iir_filter<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]);
+ }
+
+ } /* namespace kernel */
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_IIR_FILTER_H */
+
diff --git a/gr-filter/include/filter/iir_filter_ffd.h b/gr-filter/include/filter/iir_filter_ffd.h
new file mode 100644
index 0000000000..04dd1e7767
--- /dev/null
+++ b/gr-filter/include/filter/iir_filter_ffd.h
@@ -0,0 +1,82 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_IIR_FILTER_FFD_H
+#define INCLUDED_IIR_FILTER_FFD_H
+
+#include <filter/api.h>
+#include <gr_sync_block.h>
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \brief IIR filter with float input, float output and double taps
+ * \ingroup filter_blk
+ *
+ * This filter uses the Direct Form I implementation, where
+ * \p fftaps contains the feed-forward taps, and \p fbtaps the feedback ones.
+ *
+ *
+ * The input and output satisfy a difference equation of the form
+ \htmlonly
+ \f{
+ y[n] - \sum_{k=1}^{M} a_k y[n-k] = \sum_{k=0}^{N} b_k x[n-k]
+ \f}
+ \endhtmlonly
+
+ \xmlonly
+ y[n] - \sum_{k=1}^{M} a_k y[n-k] = \sum_{k=0}^{N} b_k x[n-k]
+ \endxmlonly
+
+ * with the corresponding rational system function
+ \htmlonly
+ \f{
+ H(z) = \ frac{\sum_{k=0}^{M} b_k z^{-k}}{1 - \sum_{k=1}^{N} a_k z^{-k}}
+ \f}
+ \endhtmlonly
+
+ \xmlonly
+ H(z) = \ frac{\sum_{k=0}^{M} b_k z^{-k}}{1 - \sum_{k=1}^{N} a_k z^{-k}}
+ \endxmlonly
+
+ * Note that some texts define the system function with a + in the
+ * denominator. If you're using that convention, you'll need to
+ * negate the feedback taps.
+ */
+ class FILTER_API iir_filter_ffd : virtual public gr_sync_block
+ {
+ public:
+ // gr::filter::iir_filter_ffd::sptr
+ typedef boost::shared_ptr<iir_filter_ffd> sptr;
+
+ static sptr make(const std::vector<double> &fftaps,
+ const std::vector<double> &fbtaps);
+
+ virtual void set_taps(const std::vector<double> &fftaps,
+ const std::vector<double> &fbtaps) = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_IIR_FILTER_FFD_H */
diff --git a/gr-filter/include/filter/interp_fir_filter_XXX.h.t b/gr-filter/include/filter/interp_fir_filter_XXX.h.t
new file mode 100644
index 0000000000..b66c9f6439
--- /dev/null
+++ b/gr-filter/include/filter/interp_fir_filter_XXX.h.t
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/* @WARNING@ */
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <filter/api.h>
+#include <gr_sync_interpolator.h>
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \brief Interpolating FIR filter with @I_TYPE@ input, @O_TYPE@ output and @TAP_TYPE@ taps
+ * \ingroup filter_blk
+ *
+ * The fir_filter_XXX blocks create finite impulse response
+ * (FIR) filters that perform the convolution in the time
+ * domain:
+ *
+ * \code
+ * out = 0
+ * for i in ntaps:
+ * out += input[n-i] * taps[i]
+ * \endcode
+ *
+ * The taps are a C++ vector (or Python list) of values of the
+ * type specified by the third letter in the block's suffix. For
+ * this block, the value is of type @TAP_TYPE@. Taps can be
+ * created using the firdes or optfir tools.
+ *
+ * These versions of the filter can also act as up-samplers
+ * (or interpolators) by specifying an integer value for \p
+ * interpolation.
+ *
+ */
+ class FILTER_API @BASE_NAME@ : virtual public gr_sync_interpolator
+ {
+ public:
+ // gr::filter::@BASE_NAME@::sptr
+ typedef boost::shared_ptr<@BASE_NAME@> sptr;
+
+ /*!
+ * \brief Interpolating FIR filter with @I_TYPE@ input, @O_TYPE@ output, and @TAP_TYPE@ taps
+ * \ingroup filter_blk
+ *
+ * \param interpolation set the integer interpolation rate
+ * \param taps a vector/list of taps of type @TAP_TYPE@
+ */
+ static sptr make(unsigned interpolation,
+ const std::vector<@TAP_TYPE@> &taps);
+
+ virtual void set_taps(const std::vector<@TAP_TYPE@> &taps) = 0;
+ virtual std::vector<@TAP_TYPE@> taps() const = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* @GUARD_NAME@ */
diff --git a/gr-filter/include/filter/interpolator_taps.h b/gr-filter/include/filter/interpolator_taps.h
new file mode 100644
index 0000000000..a232edd384
--- /dev/null
+++ b/gr-filter/include/filter/interpolator_taps.h
@@ -0,0 +1,140 @@
+/*
+ * 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/gr-filter/include/filter/mmse_fir_interpolator_cc.h b/gr-filter/include/filter/mmse_fir_interpolator_cc.h
new file mode 100644
index 0000000000..0436b4a0ff
--- /dev/null
+++ b/gr-filter/include/filter/mmse_fir_interpolator_cc.h
@@ -0,0 +1,79 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2007,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _GRI_MMSE_FIR_INTERPOLATOR_CC_H_
+#define _GRI_MMSE_FIR_INTERPOLATOR_CC_H_
+
+#include <filter/api.h>
+#include <filter/fir_filter.h>
+#include <gr_complex.h>
+#include <vector>
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \brief Compute intermediate samples between signal samples x(k*Ts)
+ * \ingroup filter_primitive
+ *
+ * This implements a Mininum Mean Squared Error interpolator with
+ * 8 taps. It is suitable for signals where the bandwidth of
+ * interest B = 1/(4*Ts) Where Ts is the time between samples.
+ *
+ * Although mu, the fractional delay, is specified as a float, it
+ * is actually quantized. 0.0 <= mu <= 1.0. That is, mu is
+ * quantized in the interpolate method to 32nd's of a sample.
+ *
+ * For more information, in the GNU Radio source code, see:
+ * \li gnuradio-core/src/gen_interpolator_taps/README
+ * \li gnuradio-core/src/gen_interpolator_taps/praxis.txt
+ */
+
+ class FILTER_API mmse_fir_interpolator_cc
+ {
+ public:
+ mmse_fir_interpolator_cc();
+ ~mmse_fir_interpolator_cc();
+
+ unsigned ntaps() const;
+ unsigned nsteps() const;
+
+ /*!
+ * \brief compute a single interpolated output value.
+ *
+ * \p input must have ntaps() valid entries and be 8-byte aligned.
+ * input[0] .. input[ntaps() - 1] are referenced to compute the output value.
+ * \throws std::invalid_argument if input is not 8-byte aligned.
+ *
+ * \p mu must be in the range [0, 1] and specifies the fractional delay.
+ *
+ * \returns the interpolated input value.
+ */
+ gr_complex interpolate(const gr_complex input[], float mu) const;
+
+ protected:
+ std::vector<kernel::fir_filter_ccf *> filters;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* _MMSE_FIR_INTERPOLATOR_CC_H_ */
diff --git a/gr-filter/include/filter/mmse_fir_interpolator_ff.h b/gr-filter/include/filter/mmse_fir_interpolator_ff.h
new file mode 100644
index 0000000000..4353aa94f1
--- /dev/null
+++ b/gr-filter/include/filter/mmse_fir_interpolator_ff.h
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _MMSE_FIR_INTERPOLATOR_FF_H_
+#define _MMSE_FIR_INTERPOLATOR_FF_H_
+
+#include <filter/api.h>
+#include <filter/fir_filter.h>
+#include <vector>
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \brief Compute intermediate samples between signal samples x(k*Ts)
+ * \ingroup filter_primitive
+ *
+ * This implements a Mininum Mean Squared Error interpolator with
+ * 8 taps. It is suitable for signals where the bandwidth of
+ * interest B = 1/(4*Ts) Where Ts is the time between samples.
+ *
+ * Although mu, the fractional delay, is specified as a float, it
+ * is actually quantized. 0.0 <= mu <= 1.0. That is, mu is
+ * quantized in the interpolate method to 32nd's of a sample.
+ *
+ * For more information, in the GNU Radio source code, see:
+ * \li gnuradio-core/src/gen_interpolator_taps/README
+ * \li gnuradio-core/src/gen_interpolator_taps/praxis.txt
+ */
+ class FILTER_API mmse_fir_interpolator_ff
+ {
+ public:
+ mmse_fir_interpolator_ff();
+ ~mmse_fir_interpolator_ff();
+
+ 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<kernel::fir_filter_fff*> filters;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* _MMSE_FIR_INTERPOLATOR_FF_H_ */
diff --git a/gr-filter/include/filter/pfb_arb_resampler_ccf.h b/gr-filter/include/filter/pfb_arb_resampler_ccf.h
new file mode 100644
index 0000000000..a154e055a0
--- /dev/null
+++ b/gr-filter/include/filter/pfb_arb_resampler_ccf.h
@@ -0,0 +1,151 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_PFB_ARB_RESAMPLER_CCF_H
+#define INCLUDED_PFB_ARB_RESAMPLER_CCF_H
+
+#include <filter/api.h>
+#include <gr_block.h>
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \class pfb_arb_resampler_ccf
+ *
+ * \brief Polyphase filterbank arbitrary resampler with
+ * gr_complex input, gr_complex output and float taps
+ *
+ * \ingroup filter_blk
+ * \ingroup pfb_blk
+ *
+ * This block takes in a signal stream and performs arbitrary
+ * resampling. The resampling rate can be any real number
+ * <EM>r</EM>. The resampling is done by constructing <EM>N</EM>
+ * filters where <EM>N</EM> is the interpolation rate. We then
+ * calculate <EM>D</EM> where <EM>D = floor(N/r)</EM>.
+ *
+ * Using <EM>N</EM> and <EM>D</EM>, we can perform rational
+ * resampling where <EM>N/D</EM> is a rational number close to the
+ * input rate <EM>r</EM> where we have <EM>N</EM> filters and we
+ * cycle through them as a polyphase filterbank with a stride of
+ * <EM>D</EM> so that <EM>i+1 = (i + D) % N</EM>.
+ *
+ * To get the arbitrary rate, we want to interpolate between two
+ * points. For each value out, we take an output from the current
+ * filter, <EM>i</EM>, and the next filter <EM>i+1</EM> and then
+ * linearly interpolate between the two based on the real
+ * resampling rate we want.
+ *
+ * The linear interpolation only provides us with an approximation
+ * to the real sampling rate specified. The error is a
+ * quantization error between the two filters we used as our
+ * interpolation points. To this end, the number of filters,
+ * <EM>N</EM>, used determines the quantization error; the larger
+ * <EM>N</EM>, the smaller the noise. You can design for a
+ * specified noise floor by setting the filter size (parameters
+ * <EM>filter_size</EM>). The size defaults to 32 filters, which
+ * is about as good as most implementations need.
+ *
+ * The trick with designing this filter is in how to specify the
+ * taps of the prototype filter. Like the PFB interpolator, the
+ * taps are specified using the interpolated filter rate. In this
+ * case, that rate is the input sample rate multiplied by the
+ * number of filters in the filterbank, which is also the
+ * interpolation rate. All other values should be relative to this
+ * rate.
+ *
+ * For example, for a 32-filter arbitrary resampler and using the
+ * GNU Radio's firdes utility to build the filter, we build a
+ * low-pass filter with a sampling rate of <EM>fs</EM>, a 3-dB
+ * bandwidth of <EM>BW</EM> and a transition bandwidth of
+ * <EM>TB</EM>. We can also specify the out-of-band attenuation to
+ * use, <EM>ATT</EM>, and the filter window function (a
+ * Blackman-harris window in this case). The first input is the
+ * gain of the filter, which we specify here as the interpolation
+ * rate (<EM>32</EM>).
+ *
+ * <B><EM>self._taps = filter.firdes.low_pass_2(32, 32*fs, BW, TB,
+ * attenuation_dB=ATT, window=filter.firdes.WIN_BLACKMAN_hARRIS)</EM></B>
+ *
+ * The theory behind this block can be found in Chapter 7.5 of
+ * the following book.
+ *
+ * <B><EM>f. harris, "Multirate Signal Processing for Communication
+ * Systems", Upper Saddle River, NJ: Prentice Hall, Inc. 2004.</EM></B>
+ */
+
+ class FILTER_API pfb_arb_resampler_ccf : virtual public gr_block
+ {
+ public:
+ // gr::filter::pfb_arb_resampler_ccf::sptr
+ typedef boost::shared_ptr<pfb_arb_resampler_ccf> sptr;
+
+ /*!
+ * Build the polyphase filterbank arbitray resampler.
+ * \param rate (float) Specifies the resampling rate to use
+ * \param taps (vector/list of floats) The prototype filter to populate the filterbank. The taps
+ * should be generated at the filter_size sampling rate.
+ * \param filter_size (unsigned int) The number of filters in the filter bank. This is directly
+ * related to quantization noise introduced during the resampling.
+ * Defaults to 32 filters.
+ */
+ static sptr make(float rate,
+ const std::vector<float> &taps,
+ unsigned int filter_size=32);
+ /*!
+ * Resets the filterbank's filter taps with the new prototype filter
+ * \param taps (vector/list of floats) The prototype filter to populate the filterbank.
+ */
+ virtual void set_taps(const std::vector<float> &taps) = 0;
+
+ /*!
+ * Return a vector<vector<>> of the filterbank taps
+ */
+ virtual std::vector<std::vector<float> > taps() const = 0;
+
+ /*!
+ * Print all of the filterbank taps to screen.
+ */
+ virtual void print_taps() = 0;
+
+ /*!
+ * Sets the resampling rate of the block.
+ */
+ virtual void set_rate (float rate) = 0;
+
+ /*!
+ * Sets the current phase offset in radians (0 to 2pi).
+ */
+ virtual void set_phase(float ph) = 0;
+
+ /*!
+ * Gets the current phase of the resampler in radians (2 to 2pi).
+ */
+ virtual float phase() const = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_PFB_ARB_RESAMPLER_CCF_H */
diff --git a/gr-filter/include/filter/pfb_arb_resampler_fff.h b/gr-filter/include/filter/pfb_arb_resampler_fff.h
new file mode 100644
index 0000000000..38dcc7132b
--- /dev/null
+++ b/gr-filter/include/filter/pfb_arb_resampler_fff.h
@@ -0,0 +1,152 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009-2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_PFB_ARB_RESAMPLER_FFF_H
+#define INCLUDED_PFB_ARB_RESAMPLER_FFF_H
+
+#include <filter/api.h>
+#include <gr_block.h>
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \class pfb_arb_resampler_fff
+ *
+ * \brief Polyphase filterbank arbitrary resampler with
+ * float input, float output and float taps
+ *
+ * \ingroup filter_blk
+ * \ingroup pfb_blk
+ *
+ * This block takes in a signal stream and performs arbitrary
+ * resampling. The resampling rate can be any real number
+ * <EM>r</EM>. The resampling is done by constructing <EM>N</EM>
+ * filters where <EM>N</EM> is the interpolation rate. We then
+ * calculate <EM>D</EM> where <EM>D = floor(N/r)</EM>.
+ *
+ * Using <EM>N</EM> and <EM>D</EM>, we can perform rational
+ * resampling where <EM>N/D</EM> is a rational number close to the
+ * input rate <EM>r</EM> where we have <EM>N</EM> filters and we
+ * cycle through them as a polyphase filterbank with a stride of
+ * <EM>D</EM> so that <EM>i+1 = (i + D) % N</EM>.
+ *
+ * To get the arbitrary rate, we want to interpolate between two
+ * points. For each value out, we take an output from the current
+ * filter, <EM>i</EM>, and the next filter <EM>i+1</EM> and then
+ * linearly interpolate between the two based on the real
+ * resampling rate we want.
+ *
+ * The linear interpolation only provides us with an approximation
+ * to the real sampling rate specified. The error is a
+ * quantization error between the two filters we used as our
+ * interpolation points. To this end, the number of filters,
+ * <EM>N</EM>, used determines the quantization error; the larger
+ * <EM>N</EM>, the smaller the noise. You can design for a
+ * specified noise floor by setting the filter size (parameters
+ * <EM>filter_size</EM>). The size defaults to 32 filters, which
+ * is about as good as most implementations need.
+ *
+ * The trick with designing this filter is in how to specify the
+ * taps of the prototype filter. Like the PFB interpolator, the
+ * taps are specified using the interpolated filter rate. In this
+ * case, that rate is the input sample rate multiplied by the
+ * number of filters in the filterbank, which is also the
+ * interpolation rate. All other values should be relative to this
+ * rate.
+ *
+ * For example, for a 32-filter arbitrary resampler and using the
+ * GNU Radio's firdes utility to build the filter, we build a
+ * low-pass filter with a sampling rate of <EM>fs</EM>, a 3-dB
+ * bandwidth of <EM>BW</EM> and a transition bandwidth of
+ * <EM>TB</EM>. We can also specify the out-of-band attenuation to
+ * use, <EM>ATT</EM>, and the filter window function (a
+ * Blackman-harris window in this case). The first input is the
+ * gain of the filter, which we specify here as the interpolation
+ * rate (<EM>32</EM>).
+ *
+ * <B><EM>self._taps = filter.firdes.low_pass_2(32, 32*fs, BW, TB,
+ * attenuation_dB=ATT, window=filter.firdes.WIN_BLACKMAN_hARRIS)</EM></B>
+ *
+ * The theory behind this block can be found in Chapter 7.5 of the
+ * following book.
+ *
+ * <B><EM>f. harris, "Multirate Signal Processing for Communication
+ * Systems", Upper Saddle River, NJ: Prentice Hall, Inc. 2004.</EM></B>
+ */
+
+ class FILTER_API pfb_arb_resampler_fff : virtual public gr_block
+ {
+ public:
+ // gr::filter::pfb_arb_resampler_fff::sptr
+ typedef boost::shared_ptr<pfb_arb_resampler_fff> sptr;
+
+ /*!
+ * Build the polyphase filterbank arbitray resampler.
+ * \param rate (float) Specifies the resampling rate to use
+ * \param taps (vector/list of floats) The prototype filter to populate the filterbank. The taps
+ * should be generated at the filter_size sampling rate.
+ * \param filter_size (unsigned int) The number of filters in the filter bank. This is directly
+ * related to quantization noise introduced during the resampling.
+ * Defaults to 32 filters.
+ */
+ static sptr make(float rate,
+ const std::vector<float> &taps,
+ unsigned int filter_size=32);
+
+ /*!
+ * Resets the filterbank's filter taps with the new prototype filter
+ * \param taps (vector/list of floats) The prototype filter to populate the filterbank.
+ */
+ virtual void set_taps(const std::vector<float> &taps) = 0;
+
+ /*!
+ * Return a vector<vector<>> of the filterbank taps
+ */
+ virtual std::vector<std::vector<float> > taps() const = 0;
+
+ /*!
+ * Print all of the filterbank taps to screen.
+ */
+ virtual void print_taps() = 0;
+
+ /*!
+ * Sets the resampling rate of the block.
+ */
+ virtual void set_rate (float rate) = 0;
+
+ /*!
+ * Sets the current phase offset in radians (0 to 2pi).
+ */
+ virtual void set_phase(float ph) = 0;
+
+ /*!
+ * Gets the current phase of the resampler in radians (2 to 2pi).
+ */
+ virtual float phase() const = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_PFB_ARB_RESAMPLER_FFF_H */
diff --git a/gr-filter/include/filter/pfb_channelizer_ccf.h b/gr-filter/include/filter/pfb_channelizer_ccf.h
new file mode 100644
index 0000000000..2ff83b5e7e
--- /dev/null
+++ b/gr-filter/include/filter/pfb_channelizer_ccf.h
@@ -0,0 +1,204 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_FILTER_PFB_CHANNELIZER_CCF_H
+#define INCLUDED_FILTER_PFB_CHANNELIZER_CCF_H
+
+#include <filter/api.h>
+#include <gr_block.h>
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \class pfb_channelizer_ccf
+ *
+ * \brief Polyphase filterbank channelizer with
+ * gr_complex input, gr_complex output and float taps
+ *
+ * \ingroup filter_blk
+ * \ingroup pfb_blk
+ *
+ * This block takes in complex inputs and channelizes it to <EM>M</EM>
+ * channels of equal bandwidth. Each of the resulting channels is
+ * decimated to the new rate that is the input sampling rate
+ * <EM>fs</EM> divided by the number of channels, <EM>M</EM>.
+ *
+ * The PFB channelizer code takes the taps generated above and builds
+ * a set of filters. The set contains <EM>M</EM> number of filters
+ * and each filter contains ceil(taps.size()/decim) number of taps.
+ * Each tap from the filter prototype is sequentially inserted into
+ * the next filter. When all of the input taps are used, the remaining
+ * filters in the filterbank are filled out with 0's to make sure each
+ * filter has the same number of taps.
+ *
+ * Each filter operates using the gr_fir filter classs of GNU Radio,
+ * which takes the input stream at <EM>i</EM> and performs the inner
+ * product calculation to <EM>i+(n-1)</EM> where <EM>n</EM> is the
+ * number of filter taps. To efficiently handle this in the GNU Radio
+ * structure, each filter input must come from its own input
+ * stream. So the channelizer must be provided with <EM>M</EM> streams
+ * where the input stream has been deinterleaved. This is most easily
+ * done using the gr_stream_to_streams block.
+ *
+ * The output is then produced as a vector, where index <EM>i</EM> in
+ * the vector is the next sample from the <EM>i</EM>th channel. This
+ * is most easily handled by sending the output to a
+ * gr_vector_to_streams block to handle the conversion and passing
+ * <EM>M</EM> streams out.
+ *
+ * The input and output formatting is done using a hier_block2 called
+ * pfb_channelizer_ccf. This can take in a single stream and outputs
+ * <EM>M</EM> streams based on the behavior described above.
+ *
+ * The filter's taps should be based on the input sampling rate.
+ *
+ * For example, using the GNU Radio's firdes utility to building
+ * filters, we build a low-pass filter with a sampling rate of
+ * <EM>fs</EM>, a 3-dB bandwidth of <EM>BW</EM> and a transition
+ * bandwidth of <EM>TB</EM>. We can also specify the out-of-band
+ * attenuation to use, <EM>ATT</EM>, and the filter window
+ * function (a Blackman-harris window in this case). The first input
+ * is the gain of the filter, which we specify here as unity.
+ *
+ * <B><EM>self._taps = filter.firdes.low_pass_2(1, fs, BW, TB,
+ * attenuation_dB=ATT, window=filter.firdes.WIN_BLACKMAN_hARRIS)</EM></B>
+ *
+ * The filter output can also be overs ampled. The over sampling rate
+ * is the ratio of the the actual output sampling rate to the normal
+ * output sampling rate. It must be rationally related to the number
+ * of channels as N/i for i in [1,N], which gives an outputsample rate
+ * of [fs/N, fs] where fs is the input sample rate and N is the number
+ * of channels.
+ *
+ * For example, for 6 channels with fs = 6000 Hz, the normal rate is
+ * 6000/6 = 1000 Hz. Allowable oversampling rates are 6/6, 6/5, 6/4,
+ * 6/3, 6/2, and 6/1 where the output sample rate of a 6/1 oversample
+ * ratio is 6000 Hz, or 6 times the normal 1000 Hz. A rate of 6/5 = 1.2,
+ * so the output rate would be 1200 Hz.
+ *
+ * The theory behind this block can be found in Chapter 6 of
+ * the following book.
+ *
+ * <B><EM>f. harris, "Multirate Signal Processing for Communication
+ * Systems," Upper Saddle River, NJ: Prentice Hall, Inc. 2004.</EM></B>
+ *
+ */
+
+ class FILTER_API pfb_channelizer_ccf : virtual public gr_block
+ {
+ public:
+ // gr::filter::pfb_channelizer_ccf::sptr
+ typedef boost::shared_ptr<pfb_channelizer_ccf> sptr;
+
+ /*!
+ * Build the polyphase filterbank decimator.
+ * \param numchans (unsigned integer) Specifies the number of
+ * channels <EM>M</EM>
+ * \param taps (vector/list of floats) The prototype filter to
+ * populate the filterbank.
+ * \param oversample_rate (float) The over sampling rate is the
+ * ratio of the the actual output
+ * sampling rate to the normal
+ * output sampling rate. It must
+ * be rationally related to the
+ * number of channels as N/i for
+ * i in [1,N], which gives an
+ * outputsample rate of [fs/N,
+ * fs] where fs is the input
+ * sample rate and N is the
+ * number of channels.
+ *
+ * For example, for 6 channels
+ * with fs = 6000 Hz, the normal
+ * rateis 6000/6 = 1000
+ * Hz. Allowable oversampling
+ * rates are 6/6, 6/5, 6/4, 6/3,
+ * 6/2, and 6/1 where the output
+ * sample rate of a 6/1
+ * oversample ratio is 6000 Hz,
+ * or 6 times the normal 1000 Hz.
+ */
+ static sptr make(unsigned int numchans,
+ const std::vector<float> &taps,
+ float oversample_rate);
+
+ /*!
+ * Resets the filterbank's filter taps with the new prototype filter
+ * \param taps (vector/list of floats) The prototype filter to populate the filterbank.
+ */
+ virtual void set_taps(const std::vector<float> &taps) = 0;
+
+ /*!
+ * Print all of the filterbank taps to screen.
+ */
+ virtual void print_taps() = 0;
+
+ /*!
+ * Return a vector<vector<>> of the filterbank taps
+ */
+ virtual std::vector<std::vector<float> > taps() const = 0;
+
+ /*!
+ * Set the channel map. Channels are numbers as:
+ *
+ * N/2+1 | ... | N-1 | 0 | 1 | 2 | ... | N/2
+ * <------------------- 0 -------------------->
+ * freq
+ *
+ * So output stream 0 comes from channel 0, etc. Setting a new
+ * channel map allows the user to specify which channel in frequency
+ * he/she wants to got to which output stream.
+ *
+ * The map should have the same number of elements as the number
+ * of output connections from the block. The minimum value of
+ * the map is 0 (for the 0th channel) and the maximum number is
+ * N-1 where N is the number of channels.
+ *
+ * We specify M as the number of output connections made where M
+ * <= N, so only M out of N channels are driven to an output
+ * stream. The number of items in the channel map should be at
+ * least M long. If there are more channels specified, any value
+ * in the map over M-1 will be ignored. If the size of the map
+ * is less than M the behavior is unknown (we don't wish to
+ * check every entry into the work function).
+ *
+ * This means that if the channelizer is splitting the signal up
+ * into N channels but only M channels are specified in the map
+ * (where M <= N), then M output streams must be connected and
+ * the map and the channel numbers used must be less than
+ * N-1. Output channel number can be reused, too. By default,
+ * the map is [0...M-1] with M = N.
+ */
+ virtual void set_channel_map(const std::vector<int> &map) = 0;
+
+ /*!
+ * Gets the current channel map.
+ */
+ virtual std::vector<int> channel_map() const = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_PFB_CHANNELIZER_CCF_H */
diff --git a/gr-filter/include/filter/pfb_decimator_ccf.h b/gr-filter/include/filter/pfb_decimator_ccf.h
new file mode 100644
index 0000000000..bf9d0d9508
--- /dev/null
+++ b/gr-filter/include/filter/pfb_decimator_ccf.h
@@ -0,0 +1,131 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_PFB_DECIMATOR_CCF_H
+#define INCLUDED_PFB_DECIMATOR_CCF_H
+
+#include <filter/api.h>
+#include <gr_sync_block.h>
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \class pfb_decimator_ccf
+ * \brief Polyphase filterbank bandpass decimator with gr_complex
+ * input, gr_complex output and float taps
+ *
+ * \ingroup filter_blk
+ * \ingroup pfb_blk
+ *
+ * This block takes in a signal stream and performs interger down-
+ * sampling (decimation) with a polyphase filterbank. The first
+ * input is the integer specifying how much to decimate by. The
+ * second input is a vector (Python list) of floating-point taps
+ * of the prototype filter. The third input specifies the channel
+ * to extract. By default, the zeroth channel is used, which is
+ * the baseband channel (first Nyquist zone).
+ *
+ * The <EM>channel</EM> parameter specifies which channel to use
+ * since this class is capable of bandpass decimation. Given a
+ * complex input stream at a sampling rate of <EM>fs</EM> and a
+ * decimation rate of <EM>decim</EM>, the input frequency domain
+ * is split into <EM>decim</EM> channels that represent the
+ * Nyquist zones. Using the polyphase filterbank, we can select
+ * any one of these channels to decimate.
+ *
+ * The output signal will be the basebanded and decimated signal
+ * from that channel. This concept is very similar to the PFB
+ * channelizer (see #gr_pfb_channelizer_ccf) where only a single
+ * channel is extracted at a time.
+ *
+ * The filter's taps should be based on the sampling rate before
+ * decimation.
+ *
+ * For example, using the GNU Radio's firdes utility to building
+ * filters, we build a low-pass filter with a sampling rate of
+ * <EM>fs</EM>, a 3-dB bandwidth of <EM>BW</EM> and a transition
+ * bandwidth of <EM>TB</EM>. We can also specify the out-of-band
+ * attenuation to use, <EM>ATT</EM>, and the filter window
+ * function (a Blackman-harris window in this case). The first
+ * input is the gain of the filter, which we specify here as
+ * unity.
+ *
+ * <B><EM>self._taps = filter.firdes.low_pass_2(1, fs, BW, TB,
+ * attenuation_dB=ATT, window=filter.firdes.WIN_BLACKMAN_hARRIS)</EM></B>
+ *
+ * The PFB decimator code takes the taps generated above and
+ * builds a set of filters. The set contains <EM>decim</EM> number
+ * of filters and each filter contains ceil(taps.size()/decim)
+ * number of taps. Each tap from the filter prototype is
+ * sequentially inserted into the next filter. When all of the
+ * input taps are used, the remaining filters in the filterbank
+ * are filled out with 0's to make sure each filter has the same
+ * number of taps.
+ *
+ * The theory behind this block can be found in Chapter 6 of
+ * the following book.
+ *
+ * <B><EM>f. harris, "Multirate Signal Processing for Communication
+ * Systems," Upper Saddle River, NJ: Prentice Hall, Inc. 2004.</EM></B>
+ */
+
+ class FILTER_API pfb_decimator_ccf : virtual public gr_sync_block
+ {
+ public:
+ // gr::filter::pfb_decimator_ccf::sptr
+ typedef boost::shared_ptr<pfb_decimator_ccf> sptr;
+
+ /*!
+ * Build the polyphase filterbank decimator.
+ * \param decim (unsigned integer) Specifies the decimation rate to use
+ * \param taps (vector/list of floats) The prototype filter to populate the filterbank.
+ * \param channel (unsigned integer) Selects the channel to return [default=0].
+ */
+ static sptr make(unsigned int decim,
+ const std::vector<float> &taps,
+ unsigned int channel);
+
+ /*!
+ * Resets the filterbank's filter taps with the new prototype filter
+ * \param taps (vector/list of floats) The prototype filter to populate the filterbank.
+ */
+ virtual void set_taps(const std::vector<float> &taps) = 0;
+
+ /*!
+ * Return a vector<vector<>> of the filterbank taps
+ */
+ virtual std::vector<std::vector<float> > taps() const = 0;
+
+ /*!
+ * Print all of the filterbank taps to screen.
+ */
+ virtual void print_taps() = 0;
+
+ //virtual void set_channel(unsigned int channel) = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_PFB_DECIMATOR_CCF_H */
diff --git a/gr-filter/include/filter/pfb_interpolator_ccf.h b/gr-filter/include/filter/pfb_interpolator_ccf.h
new file mode 100644
index 0000000000..df28ab64d6
--- /dev/null
+++ b/gr-filter/include/filter/pfb_interpolator_ccf.h
@@ -0,0 +1,118 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_PFB_INTERPOLATOR_CCF_H
+#define INCLUDED_PFB_INTERPOLATOR_CCF_H
+
+#include <filter/api.h>
+#include <gr_sync_interpolator.h>
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \class gr_pfb_interpolator_ccf
+ *
+ * \brief Polyphase filterbank interpolator with gr_complex input,
+ * gr_complex output and float taps
+ *
+ * \ingroup filter_blk
+ * \ingroup pfb_blk
+ *
+ * This block takes in a signal stream and performs interger up-
+ * sampling (interpolation) with a polyphase filterbank. The first
+ * input is the integer specifying how much to interpolate by. The
+ * second input is a vector (Python list) of floating-point taps
+ * of the prototype filter.
+ *
+ * The filter's taps should be based on the interpolation rate
+ * specified. That is, the bandwidth specified is relative to the
+ * bandwidth after interpolation.
+ *
+ * For example, using the GNU Radio's firdes utility to building
+ * filters, we build a low-pass filter with a sampling rate of
+ * <EM>fs</EM>, a 3-dB bandwidth of <EM>BW</EM> and a transition
+ * bandwidth of <EM>TB</EM>. We can also specify the out-of-band
+ * attenuation to use, ATT, and the filter window function (a
+ * Blackman-harris window in this case). The first input is the
+ * gain, which is also specified as the interpolation rate so that
+ * the output levels are the same as the input (this creates an
+ * overall increase in power).
+ *
+ * <B><EM>self._taps = filter.firdes.low_pass_2(interp, interp*fs, BW, TB,
+ * attenuation_dB=ATT, window=filter.firdes.WIN_BLACKMAN_hARRIS)</EM></B>
+ *
+ * The PFB interpolator code takes the taps generated above and
+ * builds a set of filters. The set contains <EM>interp</EM>
+ * number of filters and each filter contains
+ * ceil(taps.size()/interp) number of taps. Each tap from the
+ * filter prototype is sequentially inserted into the next
+ * filter. When all of the input taps are used, the remaining
+ * filters in the filterbank are filled out with 0's to make sure
+ * each filter has the same number of taps.
+ *
+ * The theory behind this block can be found in Chapter 7.1 of the
+ * following book.
+ *
+ * <B><EM>f. harris, "Multirate Signal Processing for Communication
+ * Systems</EM>," Upper Saddle River, NJ: Prentice Hall,
+ * Inc. 2004.</EM></B>
+ */
+
+ class FILTER_API pfb_interpolator_ccf : virtual public gr_sync_interpolator
+ {
+ public:
+ // gr::filter::pfb_interpolator_ccf::sptr
+ typedef boost::shared_ptr<pfb_interpolator_ccf> sptr;
+
+ /*!
+ * Build the polyphase filterbank interpolator.
+ * \param interp (unsigned integer) Specifies the interpolation rate to use
+ * \param taps (vector/list of floats) The prototype filter to populate the filterbank. The taps
+ * should be generated at the interpolated sampling rate.
+ */
+ static sptr make(unsigned int interp,
+ const std::vector<float> &taps);
+
+ /*!
+ * Resets the filterbank's filter taps with the new prototype filter
+ * \param taps (vector/list of floats) The prototype filter to populate the filterbank.
+ * The taps should be generated at the interpolated sampling rate.
+ */
+ virtual void set_taps(const std::vector<float> &taps) = 0;
+
+ /*!
+ * Return a vector<vector<>> of the filterbank taps
+ */
+ virtual std::vector<std::vector<float> > taps() const = 0;
+
+ /*!
+ * Print all of the filterbank taps to screen.
+ */
+ virtual void print_taps() = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_PFB_INTERPOLATOR_CCF_H */
diff --git a/gr-filter/include/filter/pfb_synthesizer_ccf.h b/gr-filter/include/filter/pfb_synthesizer_ccf.h
new file mode 100644
index 0000000000..faa16990cc
--- /dev/null
+++ b/gr-filter/include/filter/pfb_synthesizer_ccf.h
@@ -0,0 +1,107 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_PFB_SYNTHESIZER_CCF_H
+#define INCLUDED_PFB_SYNTHESIZER_CCF_H
+
+#include <filter/api.h>
+#include <gr_sync_interpolator.h>
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \class pfb_synthesizer_ccf
+ *
+ * \brief Polyphase synthesis filterbank with
+ * gr_complex input, gr_complex output and float taps
+ *
+ * \ingroup filter_blk
+ * \ingroup pfb_blk
+ */
+
+ class FILTER_API pfb_synthesizer_ccf : virtual public gr_sync_interpolator
+ {
+ public:
+ // gr::filter::pfb_synthesizer_ccf::sptr
+ typedef boost::shared_ptr<pfb_synthesizer_ccf> sptr;
+
+ /*!
+ * Build the polyphase synthesis filterbank.
+ * \param numchans (unsigned integer) Specifies the number of
+ * channels <EM>M</EM>
+ * \param taps (vector/list of floats) The prototype filter to
+ * populate the filterbank.
+ * \param twox (bool) use 2x oversampling or not (default is no)
+ */
+ static sptr make(unsigned int numchans,
+ const std::vector<float> &taps,
+ bool twox=false);
+
+ /*!
+ * Resets the filterbank's filter taps with the new prototype filter
+ * \param taps (vector/list of floats) The prototype filter to
+ * populate the filterbank.
+ */
+ virtual void set_taps(const std::vector<float> &taps) = 0;
+
+ /*!
+ * Print all of the filterbank taps to screen.
+ */
+ virtual void print_taps() = 0;
+
+ /*!
+ * Return a vector<vector<>> of the filterbank taps
+ */
+ virtual std::vector<std::vector<float> > taps() const = 0;
+
+ /*!
+ * Set the channel map. Channels are numbers as:
+ * N/2+1 | ... | N-1 | 0 | 1 | 2 | ... | N/2
+ * <------------------- 0 -------------------->
+ * freq
+ *
+ * So input stream 0 goes to channel 0, etc. Setting a new channel
+ * map allows the user to specify where in frequency he/she wants
+ * the input stream to go. This is especially useful to avoid
+ * putting signals into the channels on the edge of the spectrum
+ * which can either wrap around (in the case of odd number of
+ * channels) and be affected by filter rolloff in the transmitter.
+ *
+ * The map must be at least the number of streams being sent to the
+ * block. Less and the algorithm will not have enough data to
+ * properly setup the buffers. Any more channels specified will be
+ * ignored.
+ */
+ virtual void set_channel_map(const std::vector<int> &map) = 0;
+
+ /*!
+ * Gets the current channel map.
+ */
+ virtual std::vector<int> channel_map() const = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_PFB_SYNTHESIZER_CCF_H */
diff --git a/gr-filter/include/filter/pm_remez.h b/gr-filter/include/filter/pm_remez.h
new file mode 100644
index 0000000000..a57e9e276d
--- /dev/null
+++ b/gr-filter/include/filter/pm_remez.h
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_FILTER_PM_REMEZ_H
+#define INCLUDED_FILTER_PM_REMEZ_H
+
+#include <filter/api.h>
+#include <gr_types.h>
+#include <string>
+#include <stdexcept>
+
+namespace gr {
+ namespace filter {
+ /*!
+ * \brief Parks-McClellan FIR filter design using Remez algorithm.
+ *
+ * \ingroup filter_design
+ *
+ * Calculates the optimal (in the Chebyshev/minimax sense) FIR
+ * filter inpulse reponse given a set of band edges, the desired
+ * reponse on those bands, and the weight given to the error in
+ * those bands.
+ *
+ * \param order filter order (number of taps in the returned filter - 1)
+ * \param bands frequency at the band edges [ b1 e1 b2 e2 b3 e3 ...]
+ * \param ampl desired amplitude at the band edges [ a(b1) a(e1) a(b2) a(e2) ...]
+ * \param error_weight weighting applied to each band (usually 1)
+ * \param filter_type one of "bandpass", "hilbert" or "differentiator"
+ * \param grid_density determines how accurately the filter will be constructed. \
+ * The minimum value is 16; higher values are slower to compute.
+ *
+ * Frequency is in the range [0, 1], with 1 being the Nyquist
+ * frequency (Fs/2)
+ *
+ * \returns vector of computed taps
+ *
+ * \throws std::runtime_error if args are invalid or calculation
+ * fails to converge.
+ */
+
+ FILTER_API std::vector<double>
+ pm_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);
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_PM_REMEZ_H */
diff --git a/gr-filter/include/filter/polyphase_filterbank.h b/gr-filter/include/filter/polyphase_filterbank.h
new file mode 100644
index 0000000000..33e9522e17
--- /dev/null
+++ b/gr-filter/include/filter/polyphase_filterbank.h
@@ -0,0 +1,148 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_FILTER_POLYPHASE_FILTERBANK_H
+#define INCLUDED_FILTER_POLYPHASE_FILTERBANK_H
+
+#include <filter/api.h>
+#include <filter/fir_filter.h>
+#include <fft/fft.h>
+
+namespace gr {
+ namespace filter {
+ namespace kernel {
+
+ /*!
+ * \class polyphase_filterbank
+ *
+ * \brief Polyphase filterbank parent class
+ *
+ * \ingroup filter_blk
+ * \ingroup pfb_blk
+ *
+ * This block takes in complex inputs and channelizes it to
+ * <EM>M</EM> channels of equal bandwidth. Each of the resulting
+ * channels is decimated to the new rate that is the input
+ * sampling rate <EM>fs</EM> divided by the number of channels,
+ * <EM>M</EM>.
+ *
+ * The PFB channelizer code takes the taps generated above and
+ * builds a set of filters. The set contains <EM>M</EM> number
+ * of filters and each filter contains ceil(taps.size()/decim)
+ * number of taps. Each tap from the filter prototype is
+ * sequentially inserted into the next filter. When all of the
+ * input taps are used, the remaining filters in the filterbank
+ * are filled out with 0's to make sure each filter has the same
+ * number of taps.
+ *
+ * Each filter operates using the gr_fir filter classs of GNU
+ * Radio, which takes the input stream at <EM>i</EM> and
+ * performs the inner product calculation to <EM>i+(n-1)</EM>
+ * where <EM>n</EM> is the number of filter taps. To efficiently
+ * handle this in the GNU Radio structure, each filter input
+ * must come from its own input stream. So the channelizer must
+ * be provided with <EM>M</EM> streams where the input stream
+ * has been deinterleaved. This is most easily done using the
+ * gr_stream_to_streams block.
+ *
+ * The output is then produced as a vector, where index
+ * <EM>i</EM> in the vector is the next sample from the
+ * <EM>i</EM>th channel. This is most easily handled by sending
+ * the output to a gr_vector_to_streams block to handle the
+ * conversion and passing <EM>M</EM> streams out.
+ *
+ * The input and output formatting is done using a hier_block2
+ * called pfb_channelizer_ccf. This can take in a single stream
+ * and outputs <EM>M</EM> streams based on the behavior
+ * described above.
+ *
+ * The filter's taps should be based on the input sampling rate.
+ *
+ * For example, using the GNU Radio's firdes utility to building
+ * filters, we build a low-pass filter with a sampling rate of
+ * <EM>fs</EM>, a 3-dB bandwidth of <EM>BW</EM> and a transition
+ * bandwidth of <EM>TB</EM>. We can also specify the out-of-band
+ * attenuation to use, <EM>ATT</EM>, and the filter window
+ * function (a Blackman-harris window in this case). The first
+ * input is the gain of the filter, which we specify here as
+ * unity.
+ *
+ * <B><EM>self._taps = filter.firdes.low_pass_2(1, fs, BW, TB,
+ * attenuation_dB=ATT, window=filter.firdes.WIN_BLACKMAN_hARRIS)</EM></B>
+ *
+ * More on the theory of polyphase filterbanks can be found in
+ * the following book.
+ *
+ * <B><EM>f. harris, "Multirate Signal Processing for
+ * Communication Systems," Upper Saddle River, NJ:
+ * Prentice Hall, Inc. 2004.</EM></B>
+ *
+ */
+
+ class FILTER_API polyphase_filterbank
+ {
+ protected:
+ unsigned int d_nfilts;
+ std::vector<kernel::fir_filter_ccf*> d_filters;
+ std::vector< std::vector<float> > d_taps;
+ unsigned int d_taps_per_filter;
+ fft::fft_complex *d_fft;
+
+ public:
+ /*!
+ * Build the polyphase filterbank decimator.
+ * \param nfilts (unsigned integer) Specifies the number of
+ * channels <EM>M</EM>
+ * \param taps (vector/list of floats) The prototype filter to
+ * populate the filterbank.
+ */
+ polyphase_filterbank(unsigned int nfilts,
+ const std::vector<float> &taps);
+
+ ~polyphase_filterbank();
+
+ /*!
+ * Update the filterbank's filter taps from a prototype
+ * filter.
+ *
+ * \param taps (vector/list of floats) The prototype filter to
+ * populate the filterbank.
+ */
+ void set_taps(const std::vector<float> &taps);
+
+ /*!
+ * Print all of the filterbank taps to screen.
+ */
+ void print_taps();
+
+ /*!
+ * Return a vector<vector<>> of the filterbank taps
+ */
+ std::vector<std::vector<float> > taps() const;
+ };
+
+ } /* namespace kernel */
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_POLYPHASE_FILTERBANK_H */
diff --git a/gr-filter/include/filter/rational_resampler_base_XXX.h.t b/gr-filter/include/filter/rational_resampler_base_XXX.h.t
new file mode 100644
index 0000000000..e47a16ec6d
--- /dev/null
+++ b/gr-filter/include/filter/rational_resampler_base_XXX.h.t
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/* @WARNING@ */
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <filter/api.h>
+#include <gr_block.h>
+
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \brief Rational Resampling Polyphase FIR filter with @I_TYPE@
+ * input, @O_TYPE@ output and @TAP_TYPE@ taps.
+ *
+ *\ingroup filter_blk
+ */
+ class FILTER_API @NAME@ : virtual public gr_block
+ {
+ public:
+ // gr::filter::@BASE_NAME@::sptr
+ typedef boost::shared_ptr<@BASE_NAME@> sptr;
+
+ static sptr make(unsigned interpolation,
+ unsigned decimation,
+ const std::vector<@TAP_TYPE@> &taps);
+
+ virtual unsigned interpolation() const = 0;
+ virtual unsigned decimation() const = 0;
+
+ virtual void set_taps(const std::vector<@TAP_TYPE@> &taps) = 0;
+ virtual std::vector<@TAP_TYPE@> taps() const = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* @GUARD_NAME@ */
diff --git a/gr-filter/include/filter/single_pole_iir.h b/gr-filter/include/filter/single_pole_iir.h
new file mode 100644
index 0000000000..10d1b4791b
--- /dev/null
+++ b/gr-filter/include/filter/single_pole_iir.h
@@ -0,0 +1,200 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2006,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_SINGLE_POLE_IIR_H
+#define INCLUDED_SINGLE_POLE_IIR_H
+
+#include <filter/api.h>
+#include <stdexcept>
+#include <gr_complex.h>
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \brief class template for single pole IIR filter
+ */
+ template<class o_type, class i_type, class tap_type>
+ class single_pole_iir
+ {
+ public:
+ /*!
+ * \brief construct new single pole IIR with given alpha
+ *
+ * computes y(i) = (1-alpha) * y(i-1) + alpha * x(i)
+ */
+ single_pole_iir(tap_type alpha = 1.0)
+ {
+ d_prev_output = 0;
+ set_taps(alpha);
+ }
+
+ /*!
+ * \brief compute a single output value.
+ * \returns the filtered input value.
+ */
+ o_type filter(const i_type input);
+
+ /*!
+ * \brief compute an array of N output values.
+ * \p input must have n valid entries.
+ */
+ void filterN(o_type output[], const i_type input[], unsigned long n);
+
+ /*!
+ * \brief install \p alpha as the current taps.
+ */
+ void set_taps(tap_type alpha)
+ {
+ if(alpha < 0 || alpha > 1)
+ throw std::out_of_range("Alpha must be in [0, 1]\n");
+
+ d_alpha = alpha;
+ d_one_minus_alpha = 1.0 - alpha;
+ }
+
+ //! reset state to zero
+ void reset()
+ {
+ d_prev_output = 0;
+ }
+
+ o_type prev_output() const { return d_prev_output; }
+
+ protected:
+ tap_type d_alpha;
+ tap_type d_one_minus_alpha;
+ o_type d_prev_output;
+ };
+
+ //
+ // general case. We may want to specialize this
+ //
+ template<class o_type, class i_type, class tap_type>
+ o_type
+ single_pole_iir<o_type, i_type, tap_type>::filter(const i_type input)
+ {
+ o_type output;
+
+ output = d_alpha * input + d_one_minus_alpha * d_prev_output;
+ d_prev_output = output;
+
+ return (o_type) output;
+ }
+
+
+ template<class o_type, class i_type, class tap_type>
+ void
+ 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 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)
+ */
+ single_pole_iir(double alpha = 1.0)
+ {
+ d_prev_output = 0;
+ set_taps(alpha);
+ }
+
+ /*!
+ * \brief compute a single output value.
+ * \returns the filtered input value.
+ */
+ gr_complex filter(const i_type input);
+
+ /*!
+ * \brief compute an array of N output values.
+ * \p input must have n valid entries.
+ */
+ void filterN(gr_complex output[], const i_type input[], unsigned long n);
+
+ /*!
+ * \brief install \p alpha as the current taps.
+ */
+ void set_taps(double alpha)
+ {
+ if(alpha < 0 || alpha > 1)
+ throw std::out_of_range("Alpha must be in [0, 1]\n");
+
+ d_alpha = alpha;
+ d_one_minus_alpha = 1.0 - alpha;
+ }
+
+ //! reset state to zero
+ void reset()
+ {
+ d_prev_output = 0;
+ }
+
+ gr_complexd prev_output() const { return d_prev_output; }
+
+ protected:
+ double d_alpha;
+ double d_one_minus_alpha;
+ gr_complexd d_prev_output;
+ };
+
+ template< class i_type>
+ gr_complex
+ 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
+ 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]);
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_SINGLE_POLE_IIR_H */
diff --git a/gr-filter/include/filter/single_pole_iir_filter_cc.h b/gr-filter/include/filter/single_pole_iir_filter_cc.h
new file mode 100644
index 0000000000..82febe8ec4
--- /dev/null
+++ b/gr-filter/include/filter/single_pole_iir_filter_cc.h
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004-2006,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_SINGLE_POLE_IIR_FILTER_CC_H
+#define INCLUDED_SINGLE_POLE_IIR_FILTER_CC_H
+
+#include <filter/api.h>
+#include <filter/single_pole_iir.h>
+#include <gr_sync_block.h>
+#include <gr_complex.h>
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \brief single pole IIR filter with complex input, complex output
+ * \ingroup filter_blk
+ *
+ * The input and output satisfy a difference equation of the form
+ \htmlonly
+ \f{
+ y[n] - (1-alpha) y[n-1] = alpha x[n]
+ \f}
+ \endhtmlonly
+
+ \xmlonly
+ y[n] - (1-alpha) y[n-1] = alpha x[n]
+ \endxmlonly
+
+ * with the corresponding rational system function
+ \htmlonly
+ \f{
+ H(z) = \frac{alpha}{1 - (1-alpha) z^{-1}}
+ \f}
+ \endhtmlonly
+
+ \xmlonly
+ H(z) = \ frac{alpha}{1 - (1-alpha) z^{-1}}
+ \endxmlonly
+
+ * Note that some texts define the system function with a + in the
+ * denominator. If you're using that convention, you'll need to
+ * negate the feedback tap.
+ */
+ class FILTER_API single_pole_iir_filter_cc : virtual public gr_sync_block
+ {
+ public:
+ // gr::filter::single_pole_iir_filter_cc::sptr
+ typedef boost::shared_ptr<single_pole_iir_filter_cc> sptr;
+
+ static sptr make(double alpha, unsigned int vlen=1);
+
+ virtual void set_taps(double alpha) = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_SINGLE_POLE_IIR_FILTER_CC_H */
diff --git a/gr-filter/include/filter/single_pole_iir_filter_ff.h b/gr-filter/include/filter/single_pole_iir_filter_ff.h
new file mode 100644
index 0000000000..d85688db84
--- /dev/null
+++ b/gr-filter/include/filter/single_pole_iir_filter_ff.h
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_SINGLE_POLE_IIR_FILTER_FF_H
+#define INCLUDED_SINGLE_POLE_IIR_FILTER_FF_H
+
+#include <filter/api.h>
+#include <filter/single_pole_iir.h>
+#include <gr_sync_block.h>
+#include <gr_complex.h>
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \brief single pole IIR filter with float input, float output
+ * \ingroup filter_blk
+ *
+ * The input and output satisfy a difference equation of the form
+ \htmlonly
+ \f{
+ y[n] - (1-alpha) y[n-1] = alpha x[n]
+ \f}
+ \endhtmlonly
+
+ \xmlonly
+ y[n] - (1-alpha) y[n-1] = alpha x[n]
+ \endxmlonly
+
+ * with the corresponding rational system function
+ \htmlonly
+ \f{
+ H(z) = \frac{alpha}{1 - (1-alpha) z^{-1}}
+ \f}
+ \endhtmlonly
+
+ \xmlonly
+ H(z) = \ frac{alpha}{1 - (1-alpha) z^{-1}}
+ \endxmlonly
+
+ * Note that some texts define the system function with a + in the
+ * denominator. If you're using that convention, you'll need to
+ * negate the feedback tap.
+ */
+ class FILTER_API single_pole_iir_filter_ff : virtual public gr_sync_block
+ {
+ public:
+ // gr::filter::single_pole_iir_filter_ff::sptr
+ typedef boost::shared_ptr<single_pole_iir_filter_ff> sptr;
+
+ static sptr make(double alpha, unsigned int vlen=1);
+
+ virtual void set_taps (double alpha) = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_SINGLE_POLE_IIR_FILTER_FF_H */
diff --git a/gr-filter/lib/CMakeLists.txt b/gr-filter/lib/CMakeLists.txt
new file mode 100644
index 0000000000..73d7d7bae1
--- /dev/null
+++ b/gr-filter/lib/CMakeLists.txt
@@ -0,0 +1,178 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+# generate helper scripts to expand templated files
+########################################################################
+include(GrPython)
+
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py "
+#!${PYTHON_EXECUTABLE}
+
+import sys, os, re
+sys.path.append('${GR_CORE_PYTHONPATH}')
+os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
+os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
+
+if __name__ == '__main__':
+ import build_utils
+ root, inp = sys.argv[1:3]
+ for sig in sys.argv[3:]:
+ name = re.sub ('X+', sig, root)
+ d = build_utils.standard_impl_dict2(name, sig, 'filter')
+ build_utils.expand_template(d, inp)
+")
+
+macro(expand_cc root)
+ #make a list of all the generated files
+ unset(expanded_files_cc)
+ unset(expanded_files_h)
+ foreach(sig ${ARGN})
+ string(REGEX REPLACE "X+" ${sig} name ${root})
+ list(APPEND expanded_files_cc ${CMAKE_CURRENT_BINARY_DIR}/${name}.cc)
+ list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/${name}.h)
+ endforeach(sig)
+
+ #create a command to generate the source files
+ add_custom_command(
+ OUTPUT ${expanded_files_cc}
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.cc.t
+ COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
+ ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
+ ${root} ${root}.cc.t ${ARGN}
+ )
+
+ #create a command to generate the header file
+ add_custom_command(
+ OUTPUT ${expanded_files_h}
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t
+ COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
+ ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
+ ${root} ${root}.h.t ${ARGN}
+ )
+
+ #make source files depends on headers to force generation
+ set_source_files_properties(${expanded_files_cc}
+ PROPERTIES OBJECT_DEPENDS "${expanded_files_h}"
+ )
+
+ #install rules for the generated cc files
+ list(APPEND generated_sources ${expanded_files_cc})
+ list(APPEND generated_headers ${expanded_files_h})
+endmacro(expand_cc)
+
+########################################################################
+# Invoke macro to generate various sources
+########################################################################
+expand_cc(fir_filter_XXX_impl ccc ccf fcc fff fsf scc)
+expand_cc(freq_xlating_fir_filter_XXX_impl ccc ccf fcc fcf scf scc)
+expand_cc(interp_fir_filter_XXX_impl ccc ccf fcc fff fsf scc)
+expand_cc(rational_resampler_base_XXX_impl ccc ccf fcc fff fsf scc)
+
+
+########################################################################
+# Setup the include and linker paths
+########################################################################
+include_directories(
+ ${GR_FILTER_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${VOLK_INCLUDE_DIRS}
+ ${GNURADIO_CORE_INCLUDE_DIRS}
+ ${GR_FFT_INCLUDE_DIRS}
+ ${Boost_INCLUDE_DIRS}
+ ${FFTW3F_INCLUDE_DIRS}
+ ${CPPUNIT_INCLUDE_DIRS}
+)
+
+link_directories(${FFT_LIBRARY_DIRS})
+link_directories(${Boost_LIBRARY_DIRS})
+link_directories(${FFTW3F_LIBRARY_DIRS})
+
+########################################################################
+# Setup library
+########################################################################
+list(APPEND filter_sources
+ fir_filter.cc
+ fir_filter_with_buffer.cc
+ fft_filter.cc
+ firdes.cc
+ mmse_fir_interpolator_cc.cc
+ mmse_fir_interpolator_ff.cc
+ pm_remez.cc
+ polyphase_filterbank.cc
+ ${generated_sources}
+ adaptive_fir_ccc_impl.cc
+ adaptive_fir_ccf_impl.cc
+ dc_blocker_cc_impl.cc
+ dc_blocker_ff_impl.cc
+ filter_delay_fc_impl.cc
+ fft_filter_ccc_impl.cc
+ fft_filter_fff_impl.cc
+ fractional_interpolator_cc_impl.cc
+ fractional_interpolator_ff_impl.cc
+ hilbert_fc_impl.cc
+ iir_filter_ffd_impl.cc
+ pfb_arb_resampler_ccf_impl.cc
+ pfb_arb_resampler_fff_impl.cc
+ pfb_channelizer_ccf_impl.cc
+ pfb_decimator_ccf_impl.cc
+ pfb_interpolator_ccf_impl.cc
+ pfb_synthesizer_ccf_impl.cc
+ single_pole_iir_filter_cc_impl.cc
+ single_pole_iir_filter_ff_impl.cc
+ channel_model_impl.cc
+)
+
+list(APPEND filter_libs
+ gnuradio-core
+ gnuradio-fft
+ volk
+ ${Boost_LIBRARIES}
+ ${FFTW3F_LIBRARIES}
+)
+
+add_library(gnuradio-filter SHARED ${filter_sources})
+target_link_libraries(gnuradio-filter ${filter_libs})
+GR_LIBRARY_FOO(gnuradio-filter RUNTIME_COMPONENT "filter_runtime" DEVEL_COMPONENT "filter_devel")
+add_dependencies(gnuradio-filter gnuradio-fft filter_generated_includes filter_generated_swigs)
+
+
+########################################################################
+# QA C++ Code for gr-filter
+########################################################################
+list(APPEND test_gr_filter_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/test_gr_filter.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_filter.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_firdes.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_fir_filter_with_buffer.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_mmse_fir_interpolator_cc.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_mmse_fir_interpolator_ff.cc
+)
+
+add_executable(test-gr-filter ${test_gr_filter_sources})
+target_link_libraries(
+ test-gr-filter
+ gnuradio-core
+ gnuradio-filter
+ ${CPPUNIT_LIBRARIES}
+ ${Boost_LIBRARIES}
+)
+
+GR_ADD_TEST(test_gr_filter test-gr-filter)
diff --git a/gr-filter/lib/adaptive_fir_ccc_impl.cc b/gr-filter/lib/adaptive_fir_ccc_impl.cc
new file mode 100644
index 0000000000..515ef90cd0
--- /dev/null
+++ b/gr-filter/lib/adaptive_fir_ccc_impl.cc
@@ -0,0 +1,106 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "adaptive_fir_ccc_impl.h"
+#include <gr_io_signature.h>
+
+namespace gr {
+ namespace filter {
+
+ adaptive_fir_ccc::sptr adaptive_fir_ccc::make(const char *name, int decimation,
+ const std::vector<gr_complex> &taps)
+ {
+ return gnuradio::get_initial_sptr(new adaptive_fir_ccc_impl
+ (name, decimation, taps));
+ }
+
+ adaptive_fir_ccc_impl::adaptive_fir_ccc_impl(const char *name, int decimation,
+ const std::vector<gr_complex> &taps)
+ : gr_sync_decimator(name,
+ gr_make_io_signature(1, 1, sizeof(gr_complex)),
+ gr_make_io_signature(1, 1, sizeof(gr_complex)),
+ decimation),
+ kernel::fir_filter_ccc(decimation, taps),
+ d_updated(false)
+ {
+ set_history(d_ntaps);
+ }
+
+ void
+ adaptive_fir_ccc_impl::set_taps(const std::vector<gr_complex> &taps)
+ {
+ d_new_taps = taps;
+ d_updated = true;
+ }
+
+ std::vector<gr_complex>
+ adaptive_fir_ccc_impl::taps() const
+ {
+ return kernel::fir_filter_ccc::taps();
+ }
+
+ gr_complex
+ adaptive_fir_ccc_impl::error(const gr_complex &out)
+ {
+ return 0;
+ }
+
+ void
+ adaptive_fir_ccc_impl::update_tap(gr_complex &tap, const gr_complex &in)
+ {
+ tap = tap;
+ }
+
+ int
+ adaptive_fir_ccc_impl::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) {
+ kernel::fir_filter_ccc::set_taps(d_new_taps);
+ set_history(d_ntaps);
+ d_updated = false;
+ return 0; // history requirements may have changed.
+ }
+
+ // Call base class filtering function that uses
+ // overloaded error and update_tap functions.
+ if (decimation() == 1) {
+ filterN(out, in, noutput_items);
+ }
+ else {
+ filterNdec(out, in, noutput_items,
+ decimation());
+ }
+
+ return noutput_items;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/adaptive_fir_ccc_impl.h b/gr-filter/lib/adaptive_fir_ccc_impl.h
new file mode 100644
index 0000000000..fd6274a1d6
--- /dev/null
+++ b/gr-filter/lib/adaptive_fir_ccc_impl.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_FILTER_ADAPTIVE_FIR_CCC_IMPL_H
+#define INCLUDED_FILTER_ADAPTIVE_FIR_CCC_IMPL_H
+
+#include <filter/adaptive_fir_ccc.h>
+#include <filter/fir_filter.h>
+#include <gr_types.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API adaptive_fir_ccc_impl : public adaptive_fir_ccc, public kernel::fir_filter_ccc
+ {
+ private:
+ std::vector<gr_complex> d_new_taps;
+ bool d_updated;
+
+ protected:
+ // Override to calculate error signal per output
+ gr_complex error(const gr_complex &out);
+
+ // Override to calculate new weight from old, corresponding input
+ void update_tap(gr_complex &tap, const gr_complex &in);
+
+ public:
+ void set_taps(const std::vector<gr_complex> &taps);
+ std::vector<gr_complex> taps() const;
+
+ adaptive_fir_ccc_impl(const char *name, int decimation,
+ const std::vector<gr_complex> &taps);
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_ADAPTIVE_FIR_CCC_IMPL_H */
diff --git a/gr-filter/lib/adaptive_fir_ccf_impl.cc b/gr-filter/lib/adaptive_fir_ccf_impl.cc
new file mode 100644
index 0000000000..004a9286bb
--- /dev/null
+++ b/gr-filter/lib/adaptive_fir_ccf_impl.cc
@@ -0,0 +1,106 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "adaptive_fir_ccf_impl.h"
+#include <gr_io_signature.h>
+
+namespace gr {
+ namespace filter {
+
+ adaptive_fir_ccf::sptr adaptive_fir_ccf::make(const char *name, int decimation,
+ const std::vector<float> &taps)
+ {
+ return gnuradio::get_initial_sptr(new adaptive_fir_ccf_impl
+ (name, decimation, taps));
+ }
+
+ adaptive_fir_ccf_impl::adaptive_fir_ccf_impl(const char *name, int decimation,
+ const std::vector<float> &taps)
+ : gr_sync_decimator(name,
+ gr_make_io_signature(1, 1, sizeof(gr_complex)),
+ gr_make_io_signature(1, 1, sizeof(gr_complex)),
+ decimation),
+ kernel::fir_filter_ccf(decimation, taps),
+ d_updated(false)
+ {
+ set_history(d_ntaps);
+ }
+
+ void
+ adaptive_fir_ccf_impl::set_taps(const std::vector<float> &taps)
+ {
+ d_new_taps = taps;
+ d_updated = true;
+ }
+
+ std::vector<float>
+ adaptive_fir_ccf_impl::taps()
+ {
+ return kernel::fir_filter_ccf::taps();
+ }
+
+ float
+ adaptive_fir_ccf_impl::error(const gr_complex &out)
+ {
+ return 0;
+ }
+
+ void
+ adaptive_fir_ccf_impl::update_tap(float &tap, const gr_complex &in)
+ {
+ tap = tap;
+ }
+
+ int
+ adaptive_fir_ccf_impl::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) {
+ kernel::fir_filter_ccf::set_taps(d_new_taps);
+ set_history(d_ntaps);
+ d_updated = false;
+ return 0; // history requirements may have changed.
+ }
+
+ // Call base class filtering function that uses
+ // overloaded error and update_tap functions.
+ if (decimation() == 1) {
+ filterN(out, in, noutput_items);
+ }
+ else {
+ filterNdec(out, in, noutput_items,
+ decimation());
+ }
+
+ return noutput_items;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/adaptive_fir_ccf_impl.h b/gr-filter/lib/adaptive_fir_ccf_impl.h
new file mode 100644
index 0000000000..a0c9581ea2
--- /dev/null
+++ b/gr-filter/lib/adaptive_fir_ccf_impl.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_FILTER_ADAPTIVE_FIR_CCF_IMPL_H
+#define INCLUDED_FILTER_ADAPTIVE_FIR_CCF_IMPL_H
+
+#include <filter/adaptive_fir_ccf.h>
+#include <filter/fir_filter.h>
+#include <gr_types.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API adaptive_fir_ccf_impl : public adaptive_fir_ccf, public kernel::fir_filter_ccf
+ {
+ private:
+ std::vector<float> d_new_taps;
+ bool d_updated;
+
+ protected:
+ // Override to calculate error signal per output
+ float error(const gr_complex &out);
+
+ // Override to calculate new weight from old, corresponding input
+ void update_tap(float &tap, const gr_complex &in);
+
+ public:
+ void set_taps(const std::vector<float> &taps);
+ std::vector<float> taps();
+
+ adaptive_fir_ccf_impl(const char *name, int decimation,
+ const std::vector<float> &taps);
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_ADAPTIVE_FIR_CCF_IMPL_H */
diff --git a/gr-filter/lib/channel_model_impl.cc b/gr-filter/lib/channel_model_impl.cc
new file mode 100644
index 0000000000..f9e9954794
--- /dev/null
+++ b/gr-filter/lib/channel_model_impl.cc
@@ -0,0 +1,135 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "channel_model_impl.h"
+#include <gr_io_signature.h>
+#include <iostream>
+
+namespace gr {
+ namespace filter {
+
+ channel_model::sptr
+ channel_model::make(double noise_voltage,
+ double frequency_offset,
+ double epsilon,
+ const std::vector<gr_complex> &taps,
+ double noise_seed)
+ {
+ return gnuradio::get_initial_sptr
+ (new channel_model_impl(noise_voltage,
+ frequency_offset,
+ epsilon,
+ taps,
+ noise_seed));
+ }
+
+ // Hierarchical block constructor
+ channel_model_impl::channel_model_impl(double noise_voltage,
+ double frequency_offset,
+ double epsilon,
+ const std::vector<gr_complex> &taps,
+ double noise_seed)
+ : gr_hier_block2("gr_channel_model",
+ gr_make_io_signature(1, 1, sizeof(gr_complex)),
+ gr_make_io_signature(1, 1, sizeof(gr_complex)))
+ {
+ d_taps = taps;
+ while(d_taps.size() < 2) {
+ d_taps.push_back(0);
+ }
+
+ d_timing_offset = fractional_interpolator_cc::make(0, epsilon);
+
+ d_multipath = fir_filter_ccc::make(1, d_taps);
+
+ d_noise_adder = gr_make_add_cc();
+ d_noise = gr_make_noise_source_c(GR_GAUSSIAN, noise_voltage, noise_seed);
+ d_freq_offset = gr_make_sig_source_c(1, GR_SIN_WAVE, frequency_offset, 1.0, 0.0);
+ d_mixer_offset = gr_make_multiply_cc();
+
+ connect(self(), 0, d_timing_offset, 0);
+ connect(d_timing_offset, 0, d_multipath, 0);
+ connect(d_multipath, 0, d_mixer_offset, 0);
+ connect(d_freq_offset, 0, d_mixer_offset, 1);
+ connect(d_mixer_offset, 0, d_noise_adder, 1);
+ connect(d_noise, 0, d_noise_adder, 0);
+ connect(d_noise_adder, 0, self(), 0);
+ }
+
+ channel_model_impl::~channel_model_impl()
+ {
+ }
+
+ void
+ channel_model_impl::set_noise_voltage(double noise_voltage)
+ {
+ d_noise->set_amplitude(noise_voltage);
+ }
+
+ void
+ channel_model_impl::set_frequency_offset(double frequency_offset)
+ {
+ d_freq_offset->set_frequency(frequency_offset);
+ }
+
+ void
+ channel_model_impl::set_taps(const std::vector<gr_complex> &taps)
+ {
+ d_taps = taps;
+ while(d_taps.size() < 2) {
+ d_taps.push_back(0);
+ }
+ d_multipath->set_taps(d_taps);
+ }
+
+ void
+ channel_model_impl::set_timing_offset(double epsilon)
+ {
+ d_timing_offset->set_interp_ratio(epsilon);
+ }
+
+ double
+ channel_model_impl::noise_voltage() const
+ {
+ return d_noise->amplitude();
+ }
+
+ double
+ channel_model_impl::frequency_offset() const
+ {
+ return d_freq_offset->frequency();
+ }
+
+ std::vector<gr_complex>
+ channel_model_impl::taps() const
+ {
+ return d_multipath->taps();
+ }
+
+ double
+ channel_model_impl::timing_offset() const
+ {
+ return d_timing_offset->interp_ratio();
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/channel_model_impl.h b/gr-filter/lib/channel_model_impl.h
new file mode 100644
index 0000000000..95a63d7904
--- /dev/null
+++ b/gr-filter/lib/channel_model_impl.h
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_FILTER_CHANNEL_MODEL_IMPL_H
+#define INCLUDED_FILTER_CHANNEL_MODEL_IMPL_H
+
+#include <gr_top_block.h>
+#include <gr_sig_source_c.h>
+#include <gr_add_cc.h>
+#include <gr_multiply_cc.h>
+#include <gr_noise_source_c.h>
+#include <filter/channel_model.h>
+#include <filter/fractional_interpolator_cc.h>
+#include <filter/fir_filter_ccc.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API channel_model_impl : public channel_model
+ {
+ private:
+ gr_sig_source_c_sptr d_freq_offset;
+ gr_add_cc_sptr d_noise_adder;
+ gr_noise_source_c_sptr d_noise;
+ gr_multiply_cc_sptr d_mixer_offset;
+
+ fractional_interpolator_cc::sptr d_timing_offset;
+ fir_filter_ccc::sptr d_multipath;
+
+ std::vector<gr_complex> d_taps;
+
+ public:
+ channel_model_impl(double noise_voltage,
+ double frequency_offset,
+ double epsilon,
+ const std::vector<gr_complex> &taps,
+ double noise_seed);
+
+ ~channel_model_impl();
+
+ void set_noise_voltage(double noise_voltage);
+ void set_frequency_offset(double frequency_offset);
+ void set_taps(const std::vector<gr_complex> &taps);
+ void set_timing_offset(double epsilon);
+
+ double noise_voltage() const;
+ double frequency_offset() const;
+ std::vector<gr_complex> taps() const;
+ double timing_offset() const;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_CHANNEL_MODEL_IMPL_H */
diff --git a/gr-filter/lib/dc_blocker_cc_impl.cc b/gr-filter/lib/dc_blocker_cc_impl.cc
new file mode 100644
index 0000000000..663ba94f1e
--- /dev/null
+++ b/gr-filter/lib/dc_blocker_cc_impl.cc
@@ -0,0 +1,144 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "dc_blocker_cc_impl.h"
+#include <gr_io_signature.h>
+#include <cstdio>
+
+namespace gr {
+ namespace filter {
+
+ moving_averager_c::moving_averager_c(int D)
+ : d_length(D), d_out(0), d_out_d1(0), d_out_d2(0)
+ {
+ d_delay_line = std::deque<gr_complex>(d_length-1, gr_complex(0,0));
+ }
+
+ moving_averager_c::~moving_averager_c()
+ {
+ }
+
+ gr_complex
+ moving_averager_c::filter(gr_complex x)
+ {
+ d_out_d1 = d_out;
+ d_delay_line.push_back(x);
+ d_out = d_delay_line[0];
+ d_delay_line.pop_front();
+
+ gr_complex y = x - d_out_d1 + d_out_d2;
+ d_out_d2 = y;
+
+ return (y / (float)(d_length));
+ }
+
+
+
+ dc_blocker_cc::sptr dc_blocker_cc::make(int D, bool long_form)
+ {
+ return gnuradio::get_initial_sptr(new dc_blocker_cc_impl(D, long_form));
+ }
+
+
+ dc_blocker_cc_impl::dc_blocker_cc_impl(int D, bool long_form)
+ : gr_sync_block("dc_blocker_cc",
+ gr_make_io_signature (1, 1, sizeof(gr_complex)),
+ gr_make_io_signature (1, 1, sizeof(gr_complex))),
+ d_length(D), d_long_form(long_form)
+ {
+ if(d_long_form) {
+ d_ma_0 = new moving_averager_c(D);
+ d_ma_1 = new moving_averager_c(D);
+ d_ma_2 = new moving_averager_c(D);
+ d_ma_3 = new moving_averager_c(D);
+ d_delay_line = std::deque<gr_complex>(d_length-1, gr_complex(0,0));
+ }
+ else {
+ d_ma_0 = new moving_averager_c(D);
+ d_ma_1 = new moving_averager_c(D);
+ }
+ }
+
+ dc_blocker_cc_impl::~dc_blocker_cc_impl()
+ {
+ if(d_long_form) {
+ delete d_ma_0;
+ delete d_ma_1;
+ delete d_ma_2;
+ delete d_ma_3;
+ }
+ else {
+ delete d_ma_0;
+ delete d_ma_1;
+ }
+ }
+
+ int
+ dc_blocker_cc_impl::group_delay()
+ {
+ if(d_long_form)
+ return (2*d_length-2);
+ else
+ return d_length - 1;
+ }
+
+ int
+ dc_blocker_cc_impl::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const gr_complex *in = (const gr_complex*)input_items[0];
+ gr_complex *out = (gr_complex*)output_items[0];
+
+ if(d_long_form) {
+ gr_complex y1, y2, y3, y4, d;
+ for(int i = 0; i < noutput_items; i++) {
+ y1 = d_ma_0->filter(in[i]);
+ y2 = d_ma_1->filter(y1);
+ y3 = d_ma_2->filter(y2);
+ y4 = d_ma_3->filter(y3);
+
+ d_delay_line.push_back(d_ma_0->delayed_sig());
+ d = d_delay_line[0];
+ d_delay_line.pop_front();
+
+ out[i] = d - y4;
+ }
+ }
+ else {
+ gr_complex y1, y2;
+ for(int i = 0; i < noutput_items; i++) {
+ y1 = d_ma_0->filter(in[i]);
+ y2 = d_ma_1->filter(y1);
+ out[i] = d_ma_0->delayed_sig() - y2;
+ }
+ }
+
+ return noutput_items;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/dc_blocker_cc_impl.h b/gr-filter/lib/dc_blocker_cc_impl.h
new file mode 100644
index 0000000000..6f8bc16c76
--- /dev/null
+++ b/gr-filter/lib/dc_blocker_cc_impl.h
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_FILTER_DC_BLOCKER_CC_IMPL_H
+#define INCLUDED_FILTER_DC_BLOCKER_CC_IMPL_H
+
+#include <filter/dc_blocker_cc.h>
+#include <deque>
+
+namespace gr {
+ namespace filter {
+
+ class moving_averager_c
+ {
+ public:
+ moving_averager_c(int D);
+ ~moving_averager_c();
+
+ gr_complex filter(gr_complex x);
+ gr_complex delayed_sig() { return d_out; }
+
+ private:
+ int d_length;
+ gr_complex d_out, d_out_d1, d_out_d2;
+ std::deque<gr_complex> d_delay_line;
+ };
+
+ class FILTER_API dc_blocker_cc_impl : public dc_blocker_cc
+ {
+ private:
+ int d_length;
+ bool d_long_form;
+ moving_averager_c *d_ma_0;
+ moving_averager_c *d_ma_1;
+ moving_averager_c *d_ma_2;
+ moving_averager_c *d_ma_3;
+ std::deque<gr_complex> d_delay_line;
+
+ public:
+ dc_blocker_cc_impl(int D, bool long_form);
+
+ ~dc_blocker_cc_impl();
+
+ int group_delay();
+
+ //int set_length(int D);
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_DC_BLOCKER_CC_IMPL_H */
diff --git a/gr-filter/lib/dc_blocker_ff_impl.cc b/gr-filter/lib/dc_blocker_ff_impl.cc
new file mode 100644
index 0000000000..22822d1476
--- /dev/null
+++ b/gr-filter/lib/dc_blocker_ff_impl.cc
@@ -0,0 +1,142 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "dc_blocker_ff_impl.h"
+#include <gr_io_signature.h>
+#include <cstdio>
+
+namespace gr {
+ namespace filter {
+
+ moving_averager_f::moving_averager_f(int D)
+ : d_length(D), d_out(0), d_out_d1(0), d_out_d2(0)
+ {
+ d_delay_line = std::deque<float>(d_length-1, 0);
+ }
+
+ moving_averager_f::~moving_averager_f()
+ {
+ }
+
+ float
+ moving_averager_f::filter(float x)
+ {
+ d_out_d1 = d_out;
+ d_delay_line.push_back(x);
+ d_out = d_delay_line[0];
+ d_delay_line.pop_front();
+
+ float y = x - d_out_d1 + d_out_d2;
+ d_out_d2 = y;
+
+ return (y / (float)(d_length));
+ }
+
+
+ dc_blocker_ff::sptr dc_blocker_ff::make(int D, bool long_form)
+ {
+ return gnuradio::get_initial_sptr(new dc_blocker_ff_impl(D, long_form));
+ }
+
+ dc_blocker_ff_impl::dc_blocker_ff_impl(int D, bool long_form)
+ : gr_sync_block("dc_blocker_ff",
+ gr_make_io_signature (1, 1, sizeof(float)),
+ gr_make_io_signature (1, 1, sizeof(float))),
+ d_length(D), d_long_form(long_form)
+ {
+ if(d_long_form) {
+ d_ma_0 = new moving_averager_f(D);
+ d_ma_1 = new moving_averager_f(D);
+ d_ma_2 = new moving_averager_f(D);
+ d_ma_3 = new moving_averager_f(D);
+ d_delay_line = std::deque<float>(d_length-1, 0);
+ }
+ else {
+ d_ma_0 = new moving_averager_f(D);
+ d_ma_1 = new moving_averager_f(D);
+ }
+ }
+
+ dc_blocker_ff_impl::~dc_blocker_ff_impl()
+ {
+ if(d_long_form) {
+ delete d_ma_0;
+ delete d_ma_1;
+ delete d_ma_2;
+ delete d_ma_3;
+ }
+ else {
+ delete d_ma_0;
+ delete d_ma_1;
+ }
+ }
+
+ int
+ dc_blocker_ff_impl::group_delay()
+ {
+ if(d_long_form)
+ return (2*d_length-2);
+ else
+ return d_length - 1;
+ }
+
+ int
+ dc_blocker_ff_impl::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const float *in = (const float*)input_items[0];
+ float *out = (float*)output_items[0];
+
+ if(d_long_form) {
+ float y1, y2, y3, y4, d;
+ for(int i = 0; i < noutput_items; i++) {
+ y1 = d_ma_0->filter(in[i]);
+ y2 = d_ma_1->filter(y1);
+ y3 = d_ma_2->filter(y2);
+ y4 = d_ma_3->filter(y3);
+
+ d_delay_line.push_back(d_ma_0->delayed_sig());
+ d = d_delay_line[0];
+ d_delay_line.pop_front();
+
+ out[i] = d - y4;
+ }
+ }
+ else {
+ float y1, y2;
+ for(int i = 0; i < noutput_items; i++) {
+ y1 = d_ma_0->filter(in[i]);
+ y2 = d_ma_1->filter(y1);
+ out[i] = d_ma_0->delayed_sig() - y2;
+ }
+ }
+
+ return noutput_items;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/dc_blocker_ff_impl.h b/gr-filter/lib/dc_blocker_ff_impl.h
new file mode 100644
index 0000000000..5ae60e2e42
--- /dev/null
+++ b/gr-filter/lib/dc_blocker_ff_impl.h
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_FILTER_DC_BLOCKER_FF_IMPL_H
+#define INCLUDED_FILTER_DC_BLOCKER_FF_IMPL_H
+
+#include <filter/dc_blocker_ff.h>
+#include <deque>
+
+namespace gr {
+ namespace filter {
+
+ class moving_averager_f
+ {
+ public:
+ moving_averager_f(int D);
+ ~moving_averager_f();
+
+ float filter(float x);
+ float delayed_sig() { return d_out; }
+
+ private:
+ int d_length;
+ float d_out, d_out_d1, d_out_d2;
+ std::deque<float> d_delay_line;
+ };
+
+ class FILTER_API dc_blocker_ff_impl : public dc_blocker_ff
+ {
+ private:
+ int d_length;
+ bool d_long_form;
+ moving_averager_f *d_ma_0;
+ moving_averager_f *d_ma_1;
+ moving_averager_f *d_ma_2;
+ moving_averager_f *d_ma_3;
+ std::deque<float> d_delay_line;
+
+ public:
+ dc_blocker_ff_impl(int D, bool long_form);
+
+ ~dc_blocker_ff_impl();
+
+ int group_delay();
+
+ //int set_length(int D);
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_DC_BLOCKER_FF_IMPL_H */
diff --git a/gr-filter/lib/fft_filter.cc b/gr-filter/lib/fft_filter.cc
new file mode 100644
index 0000000000..1b256a3dad
--- /dev/null
+++ b/gr-filter/lib/fft_filter.cc
@@ -0,0 +1,316 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <filter/fft_filter.h>
+#include <volk/volk.h>
+#include <iostream>
+#include <cstring>
+
+namespace gr {
+ namespace filter {
+ namespace kernel {
+
+ #define VERBOSE 0
+
+ fft_filter_fff::fft_filter_fff(int decimation,
+ const std::vector<float> &taps,
+ int nthreads)
+ : d_fftsize(-1), d_decimation(decimation), d_fwdfft(0),
+ d_invfft(0), d_nthreads(nthreads)
+ {
+ set_taps(taps);
+ }
+
+ fft_filter_fff::~fft_filter_fff()
+ {
+ delete d_fwdfft;
+ delete d_invfft;
+ fft::free(d_xformed_taps);
+ }
+
+ /*
+ * determines d_ntaps, d_nsamples, d_fftsize, d_xformed_taps
+ */
+ int
+ fft_filter_fff::set_taps(const std::vector<float> &taps)
+ {
+ int i = 0;
+ compute_sizes(taps.size());
+
+ d_tail.resize(tailsize());
+ for(i = 0; i < tailsize(); i++)
+ d_tail[i] = 0;
+
+ float *in = d_fwdfft->get_inbuf();
+ gr_complex *out = d_fwdfft->get_outbuf();
+
+ float scale = 1.0 / d_fftsize;
+
+ // Compute forward xform of taps.
+ // Copy taps into first ntaps slots, then pad with zeros
+ for (i = 0; i < d_ntaps; i++)
+ in[i] = taps[i] * scale;
+
+ for (; i < d_fftsize; i++)
+ in[i] = 0;
+
+ d_fwdfft->execute(); // do the xform
+
+ // now copy output to d_xformed_taps
+ for (i = 0; i < d_fftsize/2+1; i++)
+ d_xformed_taps[i] = out[i];
+
+ return d_nsamples;
+ }
+
+ // determine and set d_ntaps, d_nsamples, d_fftsize
+ void
+ fft_filter_fff::compute_sizes(int ntaps)
+ {
+ int old_fftsize = d_fftsize;
+ d_ntaps = ntaps;
+ d_fftsize = (int) (2 * pow(2.0, ceil(log(double(ntaps)) / log(2.0))));
+ d_nsamples = d_fftsize - d_ntaps + 1;
+
+ if(VERBOSE) {
+ std::cerr << "fft_filter_fff: ntaps = " << d_ntaps
+ << " fftsize = " << d_fftsize
+ << " nsamples = " << d_nsamples << std::endl;
+ }
+
+ // compute new plans
+ if(d_fftsize != old_fftsize) {
+ delete d_fwdfft;
+ delete d_invfft;
+ d_fwdfft = new fft::fft_real_fwd(d_fftsize);
+ d_invfft = new fft::fft_real_rev(d_fftsize);
+ d_xformed_taps = fft::malloc_complex(d_fftsize/2+1);
+ }
+ }
+
+ void
+ fft_filter_fff::set_nthreads(int n)
+ {
+ d_nthreads = n;
+ if(d_fwdfft)
+ d_fwdfft->set_nthreads(n);
+ if(d_invfft)
+ d_invfft->set_nthreads(n);
+ }
+
+ int
+ fft_filter_fff::nthreads() const
+ {
+ return d_nthreads;
+ }
+
+ int
+ fft_filter_fff::filter(int nitems, const float *input, float *output)
+ {
+ int dec_ctr = 0;
+ int j = 0;
+ int ninput_items = nitems * d_decimation;
+
+ for (int i = 0; i < ninput_items; i += d_nsamples){
+
+ memcpy(d_fwdfft->get_inbuf(), &input[i], d_nsamples * sizeof(float));
+
+ for (j = d_nsamples; j < d_fftsize; j++)
+ d_fwdfft->get_inbuf()[j] = 0;
+
+ d_fwdfft->execute(); // compute fwd xform
+
+ gr_complex *a = d_fwdfft->get_outbuf();
+ gr_complex *b = d_xformed_taps;
+ gr_complex *c = d_invfft->get_inbuf();
+
+ volk_32fc_x2_multiply_32fc_a(c, a, b, d_fftsize/2+1);
+
+ d_invfft->execute(); // compute inv xform
+
+ // add in the overlapping tail
+ for (j = 0; j < tailsize(); j++)
+ d_invfft->get_outbuf()[j] += d_tail[j];
+
+ // copy nsamples to output
+ j = dec_ctr;
+ while (j < d_nsamples) {
+ *output++ = d_invfft->get_outbuf()[j];
+ j += d_decimation;
+ }
+ dec_ctr = (j - d_nsamples);
+
+ // stash the tail
+ memcpy(&d_tail[0], d_invfft->get_outbuf() + d_nsamples,
+ tailsize() * sizeof(float));
+ }
+
+ return nitems;
+ }
+
+
+ /**************************************************************/
+
+
+ fft_filter_ccc::fft_filter_ccc(int decimation,
+ const std::vector<gr_complex> &taps,
+ int nthreads)
+ : d_fftsize(-1), d_decimation(decimation), d_fwdfft(0),
+ d_invfft(0), d_nthreads(nthreads)
+ {
+ set_taps(taps);
+ }
+
+ fft_filter_ccc::~fft_filter_ccc()
+ {
+ delete d_fwdfft;
+ delete d_invfft;
+ fft::free(d_xformed_taps);
+ }
+
+ /*
+ * determines d_ntaps, d_nsamples, d_fftsize, d_xformed_taps
+ */
+ int
+ fft_filter_ccc::set_taps(const std::vector<gr_complex> &taps)
+ {
+ int i = 0;
+ compute_sizes(taps.size());
+
+ d_tail.resize(tailsize());
+ for(i = 0; i < tailsize(); i++)
+ d_tail[i] = 0;
+
+ gr_complex *in = d_fwdfft->get_inbuf();
+ gr_complex *out = d_fwdfft->get_outbuf();
+
+ float scale = 1.0 / d_fftsize;
+
+ // Compute forward xform of taps.
+ // Copy taps into first ntaps slots, then pad with zeros
+ for(i = 0; i < d_ntaps; i++)
+ in[i] = taps[i] * scale;
+
+ for(; i < d_fftsize; i++)
+ in[i] = 0;
+
+ d_fwdfft->execute(); // do the xform
+
+ // now copy output to d_xformed_taps
+ for(i = 0; i < d_fftsize; i++)
+ d_xformed_taps[i] = out[i];
+
+ return d_nsamples;
+ }
+
+ // determine and set d_ntaps, d_nsamples, d_fftsize
+ void
+ fft_filter_ccc::compute_sizes(int ntaps)
+ {
+ int old_fftsize = d_fftsize;
+ d_ntaps = ntaps;
+ d_fftsize = (int) (2 * pow(2.0, ceil(log(double(ntaps)) / log(2.0))));
+ d_nsamples = d_fftsize - d_ntaps + 1;
+
+ if(VERBOSE) {
+ std::cerr << "fft_filter_ccc: ntaps = " << d_ntaps
+ << " fftsize = " << d_fftsize
+ << " nsamples = " << d_nsamples << std::endl;
+ }
+
+ // compute new plans
+ if(d_fftsize != old_fftsize) {
+ delete d_fwdfft;
+ delete d_invfft;
+ d_fwdfft = new fft::fft_complex(d_fftsize, true, d_nthreads);
+ d_invfft = new fft::fft_complex(d_fftsize, false, d_nthreads);
+ d_xformed_taps = fft::malloc_complex(d_fftsize);
+ }
+ }
+
+ void
+ fft_filter_ccc::set_nthreads(int n)
+ {
+ d_nthreads = n;
+ if(d_fwdfft)
+ d_fwdfft->set_nthreads(n);
+ if(d_invfft)
+ d_invfft->set_nthreads(n);
+ }
+
+ int
+ fft_filter_ccc::nthreads() const
+ {
+ return d_nthreads;
+ }
+
+ int
+ fft_filter_ccc::filter(int nitems, const gr_complex *input, gr_complex *output)
+ {
+ int dec_ctr = 0;
+ int j = 0;
+ int ninput_items = nitems * d_decimation;
+
+ for(int i = 0; i < ninput_items; i += d_nsamples) {
+ memcpy(d_fwdfft->get_inbuf(), &input[i], d_nsamples * sizeof(gr_complex));
+
+ for(j = d_nsamples; j < d_fftsize; j++)
+ d_fwdfft->get_inbuf()[j] = 0;
+
+ d_fwdfft->execute(); // compute fwd xform
+
+ gr_complex *a = d_fwdfft->get_outbuf();
+ gr_complex *b = d_xformed_taps;
+ gr_complex *c = d_invfft->get_inbuf();
+
+ volk_32fc_x2_multiply_32fc_a(c, a, b, d_fftsize);
+
+ d_invfft->execute(); // compute inv xform
+
+ // add in the overlapping tail
+
+ for(j = 0; j < tailsize(); j++)
+ d_invfft->get_outbuf()[j] += d_tail[j];
+
+ // copy nsamples to output
+ j = dec_ctr;
+ while(j < d_nsamples) {
+ *output++ = d_invfft->get_outbuf()[j];
+ j += d_decimation;
+ }
+ dec_ctr = (j - d_nsamples);
+
+ // stash the tail
+ memcpy(&d_tail[0], d_invfft->get_outbuf() + d_nsamples,
+ tailsize() * sizeof(gr_complex));
+ }
+
+ return nitems;
+ }
+
+ } /* namespace kernel */
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/fft_filter_ccc_impl.cc b/gr-filter/lib/fft_filter_ccc_impl.cc
new file mode 100644
index 0000000000..0a20029917
--- /dev/null
+++ b/gr-filter/lib/fft_filter_ccc_impl.cc
@@ -0,0 +1,118 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "fft_filter_ccc_impl.h"
+#include <gr_io_signature.h>
+
+#include <math.h>
+#include <assert.h>
+#include <stdexcept>
+
+namespace gr {
+ namespace filter {
+
+ fft_filter_ccc::sptr fft_filter_ccc::make(int decimation,
+ const std::vector<gr_complex> &taps,
+ int nthreads)
+ {
+ return gnuradio::get_initial_sptr(new fft_filter_ccc_impl
+ (decimation, taps, nthreads));
+ }
+
+ fft_filter_ccc_impl::fft_filter_ccc_impl(int decimation,
+ const std::vector<gr_complex> &taps,
+ int nthreads)
+ : gr_sync_decimator("fft_filter_ccc",
+ gr_make_io_signature (1, 1, sizeof(gr_complex)),
+ gr_make_io_signature (1, 1, sizeof(gr_complex)),
+ decimation),
+ d_updated(false)
+ {
+ set_history(1);
+
+ d_filter = new kernel::fft_filter_ccc(decimation, taps, nthreads);
+
+ d_new_taps = taps;
+ d_nsamples = d_filter->set_taps(taps);
+ set_output_multiple(d_nsamples);
+ }
+
+ fft_filter_ccc_impl::~fft_filter_ccc_impl()
+ {
+ delete d_filter;
+ }
+
+ void
+ fft_filter_ccc_impl::set_taps(const std::vector<gr_complex> &taps)
+ {
+ d_new_taps = taps;
+ d_updated = true;
+ }
+
+ std::vector<gr_complex>
+ fft_filter_ccc_impl::taps() const
+ {
+ return d_new_taps;
+ }
+
+ void
+ fft_filter_ccc_impl::set_nthreads(int n)
+ {
+ if(d_filter)
+ d_filter->set_nthreads(n);
+ }
+
+ int
+ fft_filter_ccc_impl::nthreads() const
+ {
+ if(d_filter)
+ return d_filter->nthreads();
+ else
+ return 0;
+ }
+
+ int
+ fft_filter_ccc_impl::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const gr_complex *in = (const gr_complex *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ if (d_updated){
+ d_nsamples = d_filter->set_taps(d_new_taps);
+ d_updated = false;
+ set_output_multiple(d_nsamples);
+ return 0; // output multiple may have changed
+ }
+
+ d_filter->filter(noutput_items, in, out);
+
+ return noutput_items;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/fft_filter_ccc_impl.h b/gr-filter/lib/fft_filter_ccc_impl.h
new file mode 100644
index 0000000000..82be009153
--- /dev/null
+++ b/gr-filter/lib/fft_filter_ccc_impl.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_FILTER_FFT_FILTER_CCC_IMPL_H
+#define INCLUDED_FILTER_FFT_FILTER_CCC_IMPL_H
+
+#include <filter/api.h>
+#include <filter/fft_filter.h>
+#include <filter/fft_filter_ccc.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API fft_filter_ccc_impl : public fft_filter_ccc
+ {
+ private:
+ int d_nsamples;
+ bool d_updated;
+ kernel::fft_filter_ccc *d_filter;
+ std::vector<gr_complex> d_new_taps;
+
+ public:
+ fft_filter_ccc_impl(int decimation,
+ const std::vector<gr_complex> &taps,
+ int nthreads=1);
+
+ ~fft_filter_ccc_impl();
+
+ void set_taps(const std::vector<gr_complex> &taps);
+ std::vector<gr_complex> taps() const;
+
+ void set_nthreads(int n);
+ int nthreads() const;
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_FFT_FILTER_CCC_IMPL_H */
diff --git a/gr-filter/lib/fft_filter_fff_impl.cc b/gr-filter/lib/fft_filter_fff_impl.cc
new file mode 100644
index 0000000000..1d6eb02db1
--- /dev/null
+++ b/gr-filter/lib/fft_filter_fff_impl.cc
@@ -0,0 +1,119 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "fft_filter_fff_impl.h"
+#include <gr_io_signature.h>
+
+#include <math.h>
+#include <assert.h>
+#include <stdexcept>
+
+namespace gr {
+ namespace filter {
+
+ fft_filter_fff::sptr fft_filter_fff::make(int decimation,
+ const std::vector<float> &taps,
+ int nthreads)
+ {
+ return gnuradio::get_initial_sptr(new fft_filter_fff_impl
+ (decimation, taps, nthreads));
+ }
+
+
+ fft_filter_fff_impl::fft_filter_fff_impl(int decimation,
+ const std::vector<float> &taps,
+ int nthreads)
+ : gr_sync_decimator("fft_filter_fff",
+ gr_make_io_signature (1, 1, sizeof(float)),
+ gr_make_io_signature (1, 1, sizeof(float)),
+ decimation),
+ d_updated(false)
+ {
+ set_history(1);
+
+ d_filter = new kernel::fft_filter_fff(decimation, taps, nthreads);
+
+ d_new_taps = taps;
+ d_nsamples = d_filter->set_taps(taps);
+ set_output_multiple(d_nsamples);
+ }
+
+ fft_filter_fff_impl::~fft_filter_fff_impl()
+ {
+ delete d_filter;
+ }
+
+ void
+ fft_filter_fff_impl::set_taps(const std::vector<float> &taps)
+ {
+ d_new_taps = taps;
+ d_updated = true;
+ }
+
+ std::vector<float>
+ fft_filter_fff_impl::taps() const
+ {
+ return d_new_taps;
+ }
+
+ void
+ fft_filter_fff_impl::set_nthreads(int n)
+ {
+ if(d_filter)
+ d_filter->set_nthreads(n);
+ }
+
+ int
+ fft_filter_fff_impl::nthreads() const
+ {
+ if(d_filter)
+ return d_filter->nthreads();
+ else
+ return 0;
+ }
+
+ int
+ fft_filter_fff_impl::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const float *in = (const float *)input_items[0];
+ float *out = (float *)output_items[0];
+
+ if (d_updated){
+ d_nsamples = d_filter->set_taps(d_new_taps);
+ d_updated = false;
+ set_output_multiple(d_nsamples);
+ return 0; // output multiple may have changed
+ }
+
+ d_filter->filter(noutput_items, in, out);
+
+ return noutput_items;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/fft_filter_fff_impl.h b/gr-filter/lib/fft_filter_fff_impl.h
new file mode 100644
index 0000000000..df35d3df7b
--- /dev/null
+++ b/gr-filter/lib/fft_filter_fff_impl.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_FILTER_FFT_FILTER_FFF_IMPL_H
+#define INCLUDED_FILTER_FFT_FILTER_FFF_IMPL_H
+
+#include <filter/api.h>
+#include <filter/fft_filter.h>
+#include <filter/fft_filter_fff.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API fft_filter_fff_impl : public fft_filter_fff
+ {
+ private:
+ int d_nsamples;
+ bool d_updated;
+ kernel::fft_filter_fff *d_filter;
+ std::vector<float> d_new_taps;
+
+ public:
+ fft_filter_fff_impl(int decimation,
+ const std::vector<float> &taps,
+ int nthreads=1);
+
+ ~fft_filter_fff_impl();
+
+ void set_taps(const std::vector<float> &taps);
+ std::vector<float> taps() const;
+
+ void set_nthreads(int n);
+ int nthreads() const;
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_FFT_FILTER_FFF_IMPL_H */
diff --git a/gr-filter/lib/filter_delay_fc_impl.cc b/gr-filter/lib/filter_delay_fc_impl.cc
new file mode 100644
index 0000000000..3bb5508642
--- /dev/null
+++ b/gr-filter/lib/filter_delay_fc_impl.cc
@@ -0,0 +1,112 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "filter_delay_fc_impl.h"
+#include <volk/volk.h>
+
+namespace gr {
+ namespace filter {
+
+ filter_delay_fc::sptr filter_delay_fc::make(const std::vector<float> &taps)
+ {
+ return gnuradio::get_initial_sptr(new filter_delay_fc_impl(taps));
+ }
+
+ filter_delay_fc_impl::filter_delay_fc_impl(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_update(false)
+ {
+ d_taps = taps;
+ d_fir = new kernel::fir_filter_fff(1, taps);
+ d_delay = d_fir->ntaps() / 2;
+ set_history(d_fir->ntaps());
+
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(float);
+ set_alignment(std::max(1, alignment_multiple));
+ }
+
+ filter_delay_fc_impl::~filter_delay_fc_impl()
+ {
+ delete d_fir;
+ }
+
+ std::vector<float>
+ filter_delay_fc_impl::taps()
+ {
+ return d_fir->taps();
+ }
+
+ void
+ filter_delay_fc_impl::set_taps(const std::vector<float> &taps)
+ {
+ // don't reset taps in case history changes
+ d_taps = taps;
+ d_update = true;
+ }
+
+ int
+ filter_delay_fc_impl::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];
+
+ if(d_update) {
+ d_fir->set_taps(d_taps);
+ d_delay = d_fir->ntaps() / 2;
+ set_history(d_fir->ntaps());
+ return 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;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/filter_delay_fc_impl.h b/gr-filter/lib/filter_delay_fc_impl.h
new file mode 100644
index 0000000000..5157d6e022
--- /dev/null
+++ b/gr-filter/lib/filter_delay_fc_impl.h
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_FILTER_FILTER_DELAY_FC_IMPL_H
+#define INCLUDED_FILTER_FILTER_DELAY_FC_IMPL_H
+
+#include <filter/filter_delay_fc.h>
+#include <filter/fir_filter.h>
+#include <gr_io_signature.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API filter_delay_fc_impl : public filter_delay_fc
+ {
+ private:
+ unsigned int d_delay;
+ kernel::fir_filter_fff *d_fir;
+ std::vector<float> d_taps;
+ bool d_update;
+
+ public:
+ filter_delay_fc_impl(const std::vector<float> &taps);
+ ~filter_delay_fc_impl();
+
+ 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);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_FILTER_DELAY_FC_IMPL_H */
diff --git a/gr-filter/lib/fir_filter.cc b/gr-filter/lib/fir_filter.cc
new file mode 100644
index 0000000000..2334058241
--- /dev/null
+++ b/gr-filter/lib/fir_filter.cc
@@ -0,0 +1,667 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <filter/fir_filter.h>
+#include <fft/fft.h>
+#include <volk/volk.h>
+#include <cstdio>
+#include <cstring>
+
+namespace gr {
+ namespace filter {
+ namespace kernel {
+
+ fir_filter_fff::fir_filter_fff(int decimation,
+ const std::vector<float> &taps)
+ {
+ d_align = volk_get_alignment();
+ d_naligned = d_align / sizeof(float);
+
+ d_aligned_taps = NULL;
+ set_taps(taps);
+
+ // Make sure the output sample is always aligned, too.
+ d_output = fft::malloc_float(1);
+ }
+
+ fir_filter_fff::~fir_filter_fff()
+ {
+ // Free all aligned taps
+ if(d_aligned_taps != NULL) {
+ for(int i = 0; i < d_naligned; i++) {
+ fft::free(d_aligned_taps[i]);
+ }
+ fft::free(d_aligned_taps);
+ d_aligned_taps = NULL;
+ }
+
+ // Free output sample
+ fft::free(d_output);
+ }
+
+ void
+ fir_filter_fff::set_taps(const std::vector<float> &taps)
+ {
+ // Free the taps if already allocated
+ if(d_aligned_taps!= NULL) {
+ for(int i = 0; i < d_naligned; i++) {
+ fft::free(d_aligned_taps[i]);
+ }
+ fft::free(d_aligned_taps);
+ d_aligned_taps = NULL;
+ }
+
+ d_ntaps = (int)taps.size();
+ d_taps = taps;
+ std::reverse(d_taps.begin(), d_taps.end());
+
+ // Make a set of taps at all possible arch alignments
+ d_aligned_taps = (float**)malloc(d_naligned*sizeof(float**));
+ for(int i = 0; i < d_naligned; i++) {
+ d_aligned_taps[i] = fft::malloc_float(d_ntaps+d_naligned-1);
+ memset(d_aligned_taps[i], 0, sizeof(float)*(d_ntaps+d_naligned-1));
+ for(unsigned int j = 0; j < d_ntaps; j++)
+ d_aligned_taps[i][i+j] = d_taps[j];
+ }
+ }
+
+ std::vector<float>
+ fir_filter_fff::taps() const
+ {
+ std::vector<float> t = d_taps;
+ std::reverse(t.begin(), t.end());
+ return t;
+ }
+
+ unsigned int
+ fir_filter_fff::ntaps() const
+ {
+ return d_ntaps;
+ }
+
+ float
+ fir_filter_fff::filter(const float input[])
+ {
+ const float *ar = (float *)((unsigned long) input & ~(d_align-1));
+ unsigned al = input - ar;
+
+ volk_32f_x2_dot_prod_32f_a(d_output, ar,
+ d_aligned_taps[al],
+ d_ntaps+al);
+ return *d_output;
+ }
+
+ void
+ fir_filter_fff::filterN(float output[],
+ const float input[],
+ unsigned long n)
+ {
+ for(unsigned long i = 0; i < n; i++) {
+ output[i] = filter(&input[i]);
+ }
+ }
+
+ void
+ fir_filter_fff::filterNdec(float output[],
+ const float input[],
+ unsigned long n,
+ unsigned int decimate)
+ {
+ unsigned long j = 0;
+ for(unsigned long i = 0; i < n; i++) {
+ output[i] = filter(&input[j]);
+ j += decimate;
+ }
+ }
+
+ /**************************************************************/
+
+ fir_filter_ccf::fir_filter_ccf(int decimation,
+ const std::vector<float> &taps)
+ {
+ d_align = volk_get_alignment();
+ d_naligned = d_align / sizeof(gr_complex);
+
+ d_aligned_taps = NULL;
+ set_taps(taps);
+
+ // Make sure the output sample is always aligned, too.
+ d_output = fft::malloc_complex(1);
+ }
+
+ fir_filter_ccf::~fir_filter_ccf()
+ {
+ // Free all aligned taps
+ if(d_aligned_taps != NULL) {
+ for(int i = 0; i < d_naligned; i++) {
+ fft::free(d_aligned_taps[i]);
+ }
+ fft::free(d_aligned_taps);
+ d_aligned_taps = NULL;
+ }
+
+ // Free output sample
+ fft::free(d_output);
+ }
+
+ void
+ fir_filter_ccf::set_taps(const std::vector<float> &taps)
+ {
+ // Free the taps if already allocated
+ if(d_aligned_taps != NULL) {
+ for(int i = 0; i < d_naligned; i++) {
+ fft::free(d_aligned_taps[i]);
+ }
+ fft::free(d_aligned_taps);
+ d_aligned_taps = NULL;
+ }
+
+ d_ntaps = (int)taps.size();
+ d_taps = taps;
+ std::reverse(d_taps.begin(), d_taps.end());
+
+ // Make a set of taps at all possible arch alignments
+ d_aligned_taps = (float**)malloc(d_naligned*sizeof(float**));
+ for(int i = 0; i < d_naligned; i++) {
+ d_aligned_taps[i] = fft::malloc_float(d_ntaps+d_naligned-1);
+ memset(d_aligned_taps[i], 0, sizeof(float)*(d_ntaps+d_naligned-1));
+ for(unsigned int j = 0; j < d_ntaps; j++)
+ d_aligned_taps[i][i+j] = d_taps[j];
+ }
+ }
+
+ std::vector<float>
+ fir_filter_ccf::taps() const
+ {
+ std::vector<float> t = d_taps;
+ std::reverse(t.begin(), t.end());
+ return t;
+ }
+
+ unsigned int
+ fir_filter_ccf::ntaps() const
+ {
+ return d_ntaps;
+ }
+
+ gr_complex
+ fir_filter_ccf::filter(const gr_complex input[])
+ {
+ const gr_complex *ar = (gr_complex *)((unsigned long) input & ~(d_align-1));
+ unsigned al = input - ar;
+
+ volk_32fc_32f_dot_prod_32fc_a(d_output, ar,
+ d_aligned_taps[al],
+ (d_ntaps+al));
+ return *d_output;
+ }
+
+ void
+ fir_filter_ccf::filterN(gr_complex output[],
+ const gr_complex input[],
+ unsigned long n)
+ {
+ for(unsigned long i = 0; i < n; i++)
+ output[i] = filter(&input[i]);
+ }
+
+
+ void
+ fir_filter_ccf::filterNdec(gr_complex output[],
+ const gr_complex input[],
+ unsigned long n,
+ unsigned int decimate)
+ {
+ unsigned long j = 0;
+ for(unsigned long i = 0; i < n; i++){
+ output[i] = filter(&input[j]);
+ j += decimate;
+ }
+ }
+
+
+ /**************************************************************/
+
+
+ fir_filter_fcc::fir_filter_fcc(int decimation,
+ const std::vector<gr_complex> &taps)
+ {
+ d_align = volk_get_alignment();
+ d_naligned = d_align / sizeof(float);
+
+ d_aligned_taps = NULL;
+ set_taps(taps);
+
+ // Make sure the output sample is always aligned, too.
+ d_output = fft::malloc_complex(1);
+ }
+
+ fir_filter_fcc::~fir_filter_fcc()
+ {
+ // Free all aligned taps
+ if(d_aligned_taps != NULL) {
+ for(int i = 0; i < d_naligned; i++) {
+ fft::free(d_aligned_taps[i]);
+ }
+ fft::free(d_aligned_taps);
+ d_aligned_taps = NULL;
+ }
+
+ // Free output sample
+ fft::free(d_output);
+ }
+
+ void
+ fir_filter_fcc::set_taps(const std::vector<gr_complex> &taps)
+ {
+ // Free the taps if already allocated
+ if(d_aligned_taps != NULL) {
+ for(int i = 0; i < d_naligned; i++) {
+ fft::free(d_aligned_taps[i]);
+ }
+ fft::free(d_aligned_taps);
+ d_aligned_taps = NULL;
+ }
+
+ d_ntaps = (int)taps.size();
+ d_taps = taps;
+ std::reverse(d_taps.begin(), d_taps.end());
+
+ // Make a set of taps at all possible arch alignments
+ d_aligned_taps = (gr_complex**)malloc(d_naligned*sizeof(gr_complex**));
+ for(int i = 0; i < d_naligned; i++) {
+ d_aligned_taps[i] = fft::malloc_complex(d_ntaps+d_naligned-1);
+ memset(d_aligned_taps[i], 0, sizeof(gr_complex)*(d_ntaps+d_naligned-1));
+ for(unsigned int j = 0; j < d_ntaps; j++)
+ d_aligned_taps[i][i+j] = d_taps[j];
+ }
+ }
+
+ std::vector<gr_complex>
+ fir_filter_fcc::taps() const
+ {
+ std::vector<gr_complex> t = d_taps;
+ std::reverse(t.begin(), t.end());
+ return t;
+ }
+
+ unsigned int
+ fir_filter_fcc::ntaps() const
+ {
+ return d_ntaps;
+ }
+
+ gr_complex
+ fir_filter_fcc::filter(const float input[])
+ {
+ const float *ar = (float *)((unsigned long) input & ~(d_align-1));
+ unsigned al = input - ar;
+
+ volk_32fc_32f_dot_prod_32fc_a(d_output,
+ d_aligned_taps[al],
+ ar,
+ (d_ntaps+al));
+ return *d_output;
+ }
+
+ void
+ fir_filter_fcc::filterN(gr_complex output[],
+ const float input[],
+ unsigned long n)
+ {
+ for(unsigned long i = 0; i < n; i++)
+ output[i] = filter(&input[i]);
+ }
+
+
+ void
+ fir_filter_fcc::filterNdec(gr_complex output[],
+ const float input[],
+ unsigned long n,
+ unsigned int decimate)
+ {
+ unsigned long j = 0;
+ for(unsigned long i = 0; i < n; i++){
+ output[i] = filter(&input[j]);
+ j += decimate;
+ }
+ }
+
+ /**************************************************************/
+
+ fir_filter_ccc::fir_filter_ccc(int decimation,
+ const std::vector<gr_complex> &taps)
+ {
+ d_align = volk_get_alignment();
+ d_naligned = d_align / sizeof(gr_complex);
+
+ d_aligned_taps = NULL;
+ set_taps(taps);
+
+ // Make sure the output sample is always aligned, too.
+ d_output = fft::malloc_complex(1);
+ }
+
+ fir_filter_ccc::~fir_filter_ccc()
+ {
+ // Free all aligned taps
+ if(d_aligned_taps != NULL) {
+ for(int i = 0; i < d_naligned; i++) {
+ fft::free(d_aligned_taps[i]);
+ }
+ fft::free(d_aligned_taps);
+ d_aligned_taps = NULL;
+ }
+
+ // Free output sample
+ fft::free(d_output);
+ }
+
+ void
+ fir_filter_ccc::set_taps(const std::vector<gr_complex> &taps)
+ {
+ // Free the taps if already allocated
+ if(d_aligned_taps != NULL) {
+ for(int i = 0; i < d_naligned; i++) {
+ fft::free(d_aligned_taps[i]);
+ }
+ fft::free(d_aligned_taps);
+ d_aligned_taps = NULL;
+ }
+
+ d_ntaps = (int)taps.size();
+ d_taps = taps;
+ std::reverse(d_taps.begin(), d_taps.end());
+
+ // Make a set of taps at all possible arch alignments
+ d_aligned_taps = (gr_complex**)malloc(d_naligned*sizeof(gr_complex**));
+ for(int i = 0; i < d_naligned; i++) {
+ d_aligned_taps[i] = fft::malloc_complex(d_ntaps+d_naligned-1);
+ memset(d_aligned_taps[i], 0, sizeof(gr_complex)*(d_ntaps+d_naligned-1));
+ for(unsigned int j = 0; j < d_ntaps; j++)
+ d_aligned_taps[i][i+j] = d_taps[j];
+ }
+ }
+
+ std::vector<gr_complex>
+ fir_filter_ccc::taps() const
+ {
+ std::vector<gr_complex> t = d_taps;
+ std::reverse(t.begin(), t.end());
+ return t;
+ }
+
+ unsigned int
+ fir_filter_ccc::ntaps() const
+ {
+ return d_ntaps;
+ }
+
+ gr_complex
+ fir_filter_ccc::filter(const gr_complex input[])
+ {
+ const gr_complex *ar = (gr_complex *)((unsigned long) input & ~(d_align-1));
+ unsigned al = input - ar;
+
+ volk_32fc_x2_dot_prod_32fc_a(d_output, ar,
+ d_aligned_taps[al],
+ (d_ntaps+al)*sizeof(gr_complex));
+ return *d_output;
+ }
+
+ void
+ fir_filter_ccc::filterN(gr_complex output[],
+ const gr_complex input[],
+ unsigned long n)
+ {
+ for(unsigned long i = 0; i < n; i++)
+ output[i] = filter(&input[i]);
+ }
+
+
+ void
+ fir_filter_ccc::filterNdec(gr_complex output[],
+ const gr_complex input[],
+ unsigned long n,
+ unsigned int decimate)
+ {
+ unsigned long j = 0;
+ for(unsigned long i = 0; i < n; i++){
+ output[i] = filter(&input[j]);
+ j += decimate;
+ }
+ }
+
+ /**************************************************************/
+
+ fir_filter_scc::fir_filter_scc(int decimation,
+ const std::vector<gr_complex> &taps)
+ {
+ d_align = volk_get_alignment();
+ d_naligned = d_align / sizeof(short);
+
+ d_aligned_taps = NULL;
+ set_taps(taps);
+
+ // Make sure the output sample is always aligned, too.
+ d_output = fft::malloc_complex(1);
+ }
+
+ fir_filter_scc::~fir_filter_scc()
+ {
+ // Free all aligned taps
+ if(d_aligned_taps != NULL) {
+ for(int i = 0; i < d_naligned; i++) {
+ fft::free(d_aligned_taps[i]);
+ }
+ fft::free(d_aligned_taps);
+ d_aligned_taps = NULL;
+ }
+
+ // Free output sample
+ fft::free(d_output);
+ }
+
+ void
+ fir_filter_scc::set_taps(const std::vector<gr_complex> &taps)
+ {
+ // Free the taps if already allocated
+ if(d_aligned_taps != NULL) {
+ for(int i = 0; i < d_naligned; i++) {
+ fft::free(d_aligned_taps[i]);
+ }
+ fft::free(d_aligned_taps);
+ d_aligned_taps = NULL;
+ }
+
+ d_ntaps = (int)taps.size();
+ d_taps = taps;
+ std::reverse(d_taps.begin(), d_taps.end());
+
+ // Make a set of taps at all possible arch alignments
+ d_aligned_taps = (gr_complex**)malloc(d_naligned*sizeof(gr_complex**));
+ for(int i = 0; i < d_naligned; i++) {
+ d_aligned_taps[i] = fft::malloc_complex(d_ntaps+d_naligned-1);
+ memset(d_aligned_taps[i], 0, sizeof(gr_complex)*(d_ntaps+d_naligned-1));
+ for(unsigned int j = 0; j < d_ntaps; j++)
+ d_aligned_taps[i][i+j] = d_taps[j];
+ }
+ }
+
+ std::vector<gr_complex>
+ fir_filter_scc::taps() const
+ {
+ std::vector<gr_complex> t = d_taps;
+ std::reverse(t.begin(), t.end());
+ return t;
+ }
+
+ unsigned int
+ fir_filter_scc::ntaps() const
+ {
+ return d_ntaps;
+ }
+
+ gr_complex
+ fir_filter_scc::filter(const short input[])
+ {
+ const short *ar = (short *)((unsigned long) input & ~(d_align-1));
+ unsigned al = input - ar;
+
+ volk_16i_32fc_dot_prod_32fc_a(d_output, ar,
+ d_aligned_taps[al],
+ (d_ntaps+al));
+
+ return *d_output;
+ }
+
+ void
+ fir_filter_scc::filterN(gr_complex output[],
+ const short input[],
+ unsigned long n)
+ {
+ for(unsigned long i = 0; i < n; i++)
+ output[i] = filter(&input[i]);
+ }
+
+
+ void
+ fir_filter_scc::filterNdec(gr_complex output[],
+ const short input[],
+ unsigned long n,
+ unsigned int decimate)
+ {
+ unsigned long j = 0;
+ for(unsigned long i = 0; i < n; i++){
+ output[i] = filter(&input[j]);
+ j += decimate;
+ }
+ }
+
+ /**************************************************************/
+
+ fir_filter_fsf::fir_filter_fsf(int decimation,
+ const std::vector<float> &taps)
+ {
+ d_align = volk_get_alignment();
+ d_naligned = d_align / sizeof(float);
+
+ d_aligned_taps = NULL;
+ set_taps(taps);
+
+ // Make sure the output sample is always aligned, too.
+ d_output = (short*)fft::malloc_float(1);
+ }
+
+ fir_filter_fsf::~fir_filter_fsf()
+ {
+ // Free all aligned taps
+ if(d_aligned_taps != NULL) {
+ for(int i = 0; i < d_naligned; i++) {
+ fft::free(d_aligned_taps[i]);
+ }
+ fft::free(d_aligned_taps);
+ d_aligned_taps = NULL;
+ }
+
+ // Free output sample
+ fft::free(d_output);
+ }
+
+ void
+ fir_filter_fsf::set_taps(const std::vector<float> &taps)
+ {
+ // Free the taps if already allocated
+ if(d_aligned_taps != NULL) {
+ for(int i = 0; i < d_naligned; i++) {
+ fft::free(d_aligned_taps[i]);
+ }
+ fft::free(d_aligned_taps);
+ d_aligned_taps = NULL;
+ }
+
+ d_ntaps = (int)taps.size();
+ d_taps = taps;
+ std::reverse(d_taps.begin(), d_taps.end());
+
+ // Make a set of taps at all possible arch alignments
+ d_aligned_taps = (float**)malloc(d_naligned*sizeof(float**));
+ for(int i = 0; i < d_naligned; i++) {
+ d_aligned_taps[i] = fft::malloc_float(d_ntaps+d_naligned-1);
+ memset(d_aligned_taps[i], 0, sizeof(float)*(d_ntaps+d_naligned-1));
+ for(unsigned int j = 0; j < d_ntaps; j++)
+ d_aligned_taps[i][i+j] = d_taps[j];
+ }
+ }
+
+ std::vector<float>
+ fir_filter_fsf::taps() const
+ {
+ std::vector<float> t = d_taps;
+ std::reverse(t.begin(), t.end());
+ return t;
+ }
+
+ unsigned int
+ fir_filter_fsf::ntaps() const
+ {
+ return d_ntaps;
+ }
+
+ short
+ fir_filter_fsf::filter(const float input[])
+ {
+ const float *ar = (float *)((unsigned long) input & ~(d_align-1));
+ unsigned al = input - ar;
+
+ volk_32f_x2_dot_prod_16i_a(d_output, ar,
+ d_aligned_taps[al],
+ (d_ntaps+al));
+
+ return *d_output;
+ }
+
+ void
+ fir_filter_fsf::filterN(short output[],
+ const float input[],
+ unsigned long n)
+ {
+ for(unsigned long i = 0; i < n; i++)
+ output[i] = filter(&input[i]);
+ }
+
+ void
+ fir_filter_fsf::filterNdec(short output[],
+ const float input[],
+ unsigned long n,
+ unsigned int decimate)
+ {
+ unsigned long j = 0;
+ for(unsigned long i = 0; i < n; i++){
+ output[i] = filter(&input[j]);
+ j += decimate;
+ }
+ }
+
+ } /* namespace kernel */
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/fir_filter_XXX_impl.cc.t b/gr-filter/lib/fir_filter_XXX_impl.cc.t
new file mode 100644
index 0000000000..529c51e2bb
--- /dev/null
+++ b/gr-filter/lib/fir_filter_XXX_impl.cc.t
@@ -0,0 +1,104 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/* @WARNING@ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "@IMPL_NAME@.h"
+#include <gr_io_signature.h>
+#include <volk/volk.h>
+
+namespace gr {
+ namespace filter {
+
+ @BASE_NAME@::sptr
+ @BASE_NAME@::make(int decimation, const std::vector<@TAP_TYPE@> &taps)
+ {
+ return gnuradio::get_initial_sptr(new @IMPL_NAME@
+ (decimation, taps));
+ }
+
+
+ @IMPL_NAME@::@IMPL_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_fir = new kernel::@BASE_NAME@(decimation, taps);
+ d_updated = false;
+ set_history(d_fir->ntaps());
+
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(float);
+ set_alignment(std::max(1, alignment_multiple));
+ }
+
+ @IMPL_NAME@::~@IMPL_NAME@()
+ {
+ delete d_fir;
+ }
+
+ void
+ @IMPL_NAME@::set_taps(const std::vector<@TAP_TYPE@> &taps)
+ {
+ d_fir->set_taps(taps);
+ d_updated = true;
+ }
+
+ std::vector<@TAP_TYPE@>
+ @IMPL_NAME@::taps() const
+ {
+ return d_fir->taps();
+ }
+
+ int
+ @IMPL_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) {
+ 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;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
+
diff --git a/gnuradio-core/src/lib/general/gri_glfsr.h b/gr-filter/lib/fir_filter_XXX_impl.h.t
index 9aae2d9f17..ef0a7adfee 100644
--- a/gnuradio-core/src/lib/general/gri_glfsr.h
+++ b/gr-filter/lib/fir_filter_XXX_impl.h.t
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2007 Free Software Foundation, Inc.
+ * Copyright 2004,2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -20,38 +20,37 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef INCLUDED_GRI_GLFSR_H
-#define INCLUDED_GRI_GLFSR_H
+/* @WARNING@ */
-#include <gr_core_api.h>
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
-/*!
- * \brief Galois Linear Feedback Shift Register using specified polynomial mask
- * \ingroup misc
- *
- * Generates a maximal length pseudo-random sequence of length 2^degree-1
- */
+#include <filter/fir_filter.h>
+#include <filter/@BASE_NAME@.h>
+
+namespace gr {
+ namespace filter {
-class GR_CORE_API gri_glfsr
-{
- private:
- int d_shift_register;
- int d_mask;
+ class FILTER_API @IMPL_NAME@ : public @BASE_NAME@
+ {
+ private:
+ kernel::@BASE_NAME@ *d_fir;
+ bool d_updated;
- public:
+ public:
+ @IMPL_NAME@(int decimation, const std::vector<@TAP_TYPE@> &taps);
- gri_glfsr(int mask, int seed) { d_shift_register = seed; d_mask = mask; }
- static int glfsr_mask(int degree);
+ ~@IMPL_NAME@();
- unsigned char next_bit() {
- unsigned char bit = d_shift_register & 1;
- d_shift_register >>= 1;
- if (bit)
- d_shift_register ^= d_mask;
- return bit;
- }
+ void set_taps(const std::vector<@TAP_TYPE@> &taps);
+ std::vector<@TAP_TYPE@> taps() const;
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
- int mask() const { return d_mask; }
-};
+ } /* namespace filter */
+} /* namespace gr */
-#endif /* INCLUDED_GRI_GLFSR_H */ \ No newline at end of file
+#endif /* @GUARD_NAME@ */
diff --git a/gr-filter/lib/fir_filter_with_buffer.cc b/gr-filter/lib/fir_filter_with_buffer.cc
new file mode 100644
index 0000000000..7a35a92252
--- /dev/null
+++ b/gr-filter/lib/fir_filter_with_buffer.cc
@@ -0,0 +1,496 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <filter/fir_filter_with_buffer.h>
+#include <fft/fft.h>
+#include <volk/volk.h>
+#include <algorithm>
+#include <cstdio>
+#include <cstring>
+
+namespace gr {
+ namespace filter {
+ namespace kernel {
+
+ fir_filter_with_buffer_fff::fir_filter_with_buffer_fff(const std::vector<float> &taps)
+ {
+ d_align = volk_get_alignment();
+ d_naligned = d_align / sizeof(float);
+
+ d_buffer_ptr = NULL;
+ d_aligned_taps = NULL;
+ set_taps(taps);
+
+ // Make sure the output sample is always aligned, too.
+ d_output = fft::malloc_float(1);
+ }
+
+ fir_filter_with_buffer_fff::~fir_filter_with_buffer_fff()
+ {
+ if(d_buffer_ptr != NULL) {
+ fft::free(d_buffer_ptr);
+ d_buffer_ptr = NULL;
+ }
+
+ // Free aligned taps
+ if(d_aligned_taps != NULL) {
+ for(int i = 0; i < d_naligned; i++) {
+ fft::free(d_aligned_taps[i]);
+ }
+ fft::free(d_aligned_taps);
+ d_aligned_taps = NULL;
+ }
+
+ // Free output sample
+ fft::free(d_output);
+ }
+
+ void
+ fir_filter_with_buffer_fff::set_taps(const std::vector<float> &taps)
+ {
+ if(d_buffer_ptr != NULL) {
+ fft::free(d_buffer_ptr);
+ d_buffer_ptr = NULL;
+ }
+
+ // Free the taps if already allocated
+ if(d_aligned_taps != NULL) {
+ for(int i = 0; i < d_naligned; i++) {
+ fft::free(d_aligned_taps[i]);
+ }
+ fft::free(d_aligned_taps);
+ d_aligned_taps = NULL;
+ }
+
+ d_ntaps = (int)taps.size();
+ d_taps = taps;
+ std::reverse(d_taps.begin(), d_taps.end());
+
+ // We allocate enough to be able to look back and forth
+ // d_naligned beyond the buffer boundaries and make sure these
+ // are zeroed out (or they may be nan, which will cause
+ // problems). We then set d_buffer to the position in the
+ // d_buffer_ptr such that we only touch the internally
+ // allocated space.
+ d_buffer_ptr = fft::malloc_float(2*(d_ntaps + d_naligned));
+ memset(d_buffer_ptr, 0, 2*(d_ntaps + d_naligned)*sizeof(float));
+ d_buffer = d_buffer_ptr + d_naligned;
+
+ // Allocate aligned taps
+ d_aligned_taps = (float**)malloc(d_naligned*sizeof(float**));
+ for(int i = 0; i < d_naligned; i++) {
+ d_aligned_taps[i] = fft::malloc_float(d_ntaps+d_naligned-1);
+ memset(d_aligned_taps[i], 0, sizeof(float)*(d_ntaps+d_naligned-1));
+ for(unsigned int j = 0; j < d_ntaps; j++)
+ d_aligned_taps[i][i+j] = d_taps[j];
+ }
+
+ d_idx = 0;
+ }
+
+ std::vector<float>
+ fir_filter_with_buffer_fff::taps() const
+ {
+ std::vector<float> t = d_taps;
+ std::reverse(t.begin(), t.end());
+ return t;
+ }
+
+ float
+ fir_filter_with_buffer_fff::filter(float input)
+ {
+ d_buffer[d_idx] = input;
+ d_buffer[d_idx+ntaps()] = input;
+
+ d_idx++;
+ if(d_idx >= ntaps())
+ d_idx = 0;
+
+ const float *ar = (float*)((unsigned long)(&d_buffer[d_idx]) & ~(d_align-1));
+ unsigned al = (&d_buffer[d_idx]) - ar;
+
+ volk_32f_x2_dot_prod_32f_a(d_output, ar,
+ d_aligned_taps[al],
+ ntaps()+al);
+ return *d_output;
+ }
+
+ float
+ fir_filter_with_buffer_fff::filter(const float input[],
+ unsigned long dec)
+ {
+ unsigned int i;
+
+ for(i = 0; i < dec; i++) {
+ d_buffer[d_idx] = input[i];
+ d_buffer[d_idx+ntaps()] = input[i];
+ d_idx++;
+ if(d_idx >= ntaps())
+ d_idx = 0;
+ }
+
+ const float *ar = (float*)((unsigned long)(&d_buffer[d_idx]) & ~(d_align-1));
+ unsigned al = (&d_buffer[d_idx]) - ar;
+
+ volk_32f_x2_dot_prod_32f_a(d_output, ar,
+ d_aligned_taps[al],
+ ntaps()+al);
+ return *d_output;
+ }
+
+ void
+ fir_filter_with_buffer_fff::filterN(float output[],
+ const float input[],
+ unsigned long n)
+ {
+ for(unsigned long i = 0; i < n; i++) {
+ output[i] = filter(input[i]);
+ }
+ }
+
+ void
+ fir_filter_with_buffer_fff::filterNdec(float output[],
+ const float input[],
+ unsigned long n,
+ unsigned long decimate)
+ {
+ unsigned long j = 0;
+ for(unsigned long i = 0; i < n; i++) {
+ output[i] = filter(&input[j], decimate);
+ j += decimate;
+ }
+ }
+
+
+ /**************************************************************/
+
+
+ fir_filter_with_buffer_ccc::fir_filter_with_buffer_ccc(const std::vector<gr_complex> &taps)
+ {
+ d_align = volk_get_alignment();
+ d_naligned = d_align / sizeof(gr_complex);
+
+ d_buffer_ptr = NULL;
+ d_aligned_taps = NULL;
+ set_taps(taps);
+
+ // Make sure the output sample is always aligned, too.
+ d_output = fft::malloc_complex(1);
+ }
+
+ fir_filter_with_buffer_ccc::~fir_filter_with_buffer_ccc()
+ {
+ if(d_buffer_ptr != NULL) {
+ fft::free(d_buffer_ptr);
+ d_buffer_ptr = NULL;
+ }
+
+ // Free aligned taps
+ if(d_aligned_taps != NULL) {
+ for(int i = 0; i < d_naligned; i++) {
+ fft::free(d_aligned_taps[i]);
+ }
+ fft::free(d_aligned_taps);
+ d_aligned_taps = NULL;
+ }
+
+ // Free output sample
+ fft::free(d_output);
+ }
+
+ void
+ fir_filter_with_buffer_ccc::set_taps(const std::vector<gr_complex> &taps)
+ {
+ if(d_buffer_ptr != NULL) {
+ fft::free(d_buffer_ptr);
+ d_buffer_ptr = NULL;
+ }
+
+ // Free the taps if already allocated
+ if(d_aligned_taps != NULL) {
+ for(int i = 0; i < d_naligned; i++) {
+ fft::free(d_aligned_taps[i]);
+ }
+ fft::free(d_aligned_taps);
+ d_aligned_taps = NULL;
+ }
+
+ d_ntaps = (int)taps.size();
+ d_taps = taps;
+ std::reverse(d_taps.begin(), d_taps.end());
+
+ // We allocate enough to be able to look back and forth
+ // d_naligned beyond the buffer boundaries and make sure these
+ // are zeroed out (or they may be nan, which will cause
+ // problems). We then set d_buffer to the position in the
+ // d_buffer_ptr such that we only touch the internally
+ // allocated space.
+ d_buffer_ptr = fft::malloc_complex(2*(d_ntaps + d_naligned));
+ memset(d_buffer_ptr, 0, 2*(d_ntaps + d_naligned)*sizeof(gr_complex));
+ d_buffer = d_buffer_ptr + d_naligned;
+
+ // Allocate aligned taps
+ d_aligned_taps = (gr_complex**)malloc(d_naligned*sizeof(gr_complex**));
+ for(int i = 0; i < d_naligned; i++) {
+ d_aligned_taps[i] = fft::malloc_complex(d_ntaps+d_naligned-1);
+ memset(d_aligned_taps[i], 0, sizeof(gr_complex)*(d_ntaps+d_naligned-1));
+ for(unsigned int j = 0; j < d_ntaps; j++)
+ d_aligned_taps[i][i+j] = d_taps[j];
+ }
+
+ d_idx = 0;
+ }
+
+ std::vector<gr_complex>
+ fir_filter_with_buffer_ccc::taps() const
+ {
+ std::vector<gr_complex> t = d_taps;
+ std::reverse(t.begin(), t.end());
+ return t;
+ }
+
+ gr_complex
+ fir_filter_with_buffer_ccc::filter(gr_complex input)
+ {
+ d_buffer[d_idx] = input;
+ d_buffer[d_idx+ntaps()] = input;
+
+ d_idx++;
+ if(d_idx >= ntaps())
+ d_idx = 0;
+
+ const gr_complex *ar = (gr_complex *)((unsigned long)(&d_buffer[d_idx]) & ~(d_align-1));
+ unsigned al = (&d_buffer[d_idx]) - ar;
+
+ volk_32fc_x2_dot_prod_32fc_a(d_output, ar,
+ d_aligned_taps[al],
+ (ntaps()+al)*sizeof(gr_complex));
+ return *d_output;
+ }
+
+ gr_complex
+ fir_filter_with_buffer_ccc::filter(const gr_complex input[],
+ unsigned long dec)
+ {
+ unsigned int i;
+
+ for(i = 0; i < dec; i++) {
+ d_buffer[d_idx] = input[i];
+ d_buffer[d_idx+ntaps()] = input[i];
+ d_idx++;
+ if(d_idx >= ntaps())
+ d_idx = 0;
+ }
+
+ const gr_complex *ar = (gr_complex *)((unsigned long)(&d_buffer[d_idx]) & ~(d_align-1));
+ unsigned al = (&d_buffer[d_idx]) - ar;
+
+ volk_32fc_x2_dot_prod_32fc_a(d_output, ar,
+ d_aligned_taps[al],
+ (ntaps()+al)*sizeof(gr_complex));
+ return *d_output;
+ }
+
+ void
+ fir_filter_with_buffer_ccc::filterN(gr_complex output[],
+ const gr_complex input[],
+ unsigned long n)
+ {
+ for(unsigned long i = 0; i < n; i++) {
+ output[i] = filter(input[i]);
+ }
+ }
+
+ void
+ fir_filter_with_buffer_ccc::filterNdec(gr_complex output[],
+ const gr_complex input[],
+ unsigned long n,
+ unsigned long decimate)
+ {
+ unsigned long j = 0;
+ for(unsigned long i = 0; i < n; i++) {
+ output[i] = filter(&input[j], decimate);
+ j += decimate;
+ }
+ }
+
+
+ /**************************************************************/
+
+
+ fir_filter_with_buffer_ccf::fir_filter_with_buffer_ccf(const std::vector<float> &taps)
+ {
+ d_align = volk_get_alignment();
+ d_naligned = d_align / sizeof(gr_complex);
+
+ d_buffer_ptr = NULL;
+ d_aligned_taps = NULL;
+ set_taps(taps);
+
+ // Make sure the output sample is always aligned, too.
+ d_output = fft::malloc_complex(1);
+ }
+
+ fir_filter_with_buffer_ccf::~fir_filter_with_buffer_ccf()
+ {
+ if(d_buffer_ptr != NULL) {
+ fft::free(d_buffer_ptr);
+ d_buffer_ptr = NULL;
+ }
+
+ // Free aligned taps
+ if(d_aligned_taps != NULL) {
+ for(int i = 0; i < d_naligned; i++) {
+ fft::free(d_aligned_taps[i]);
+ }
+ fft::free(d_aligned_taps);
+ d_aligned_taps = NULL;
+ }
+
+ // Free output sample
+ fft::free(d_output);
+ }
+
+ void
+ fir_filter_with_buffer_ccf::set_taps(const std::vector<float> &taps)
+ {
+ if(d_buffer_ptr != NULL) {
+ fft::free(d_buffer_ptr);
+ d_buffer_ptr = NULL;
+ }
+
+ // Free the taps if already allocated
+ if(d_aligned_taps != NULL) {
+ for(int i = 0; i < d_naligned; i++) {
+ fft::free(d_aligned_taps[i]);
+ }
+ fft::free(d_aligned_taps);
+ d_aligned_taps = NULL;
+ }
+
+ d_ntaps = (int)taps.size();
+ d_taps = taps;
+ std::reverse(d_taps.begin(), d_taps.end());
+
+ // We allocate enough to be able to look back and forth
+ // d_naligned beyond the buffer boundaries and make sure these
+ // are zeroed out (or they may be nan, which will cause
+ // problems). We then set d_buffer to the position in the
+ // d_buffer_ptr such that we only touch the internally
+ // allocated space.
+ d_buffer_ptr = fft::malloc_complex(2*(d_ntaps + d_naligned));
+ memset(d_buffer_ptr, 0, 2*(d_ntaps + d_naligned)*sizeof(gr_complex));
+ d_buffer = d_buffer_ptr + d_naligned;
+
+ // Allocate aligned taps
+ d_aligned_taps = (float**)malloc(d_naligned*sizeof(float**));
+ for(int i = 0; i < d_naligned; i++) {
+ d_aligned_taps[i] = fft::malloc_float(d_ntaps+d_naligned-1);
+ memset(d_aligned_taps[i], 0, sizeof(float)*(d_ntaps+d_naligned-1));
+ for(unsigned int j = 0; j < d_ntaps; j++)
+ d_aligned_taps[i][i+j] = d_taps[j];
+ }
+
+ d_idx = 0;
+ }
+
+ std::vector<float>
+ fir_filter_with_buffer_ccf::taps() const
+ {
+ std::vector<float> t = d_taps;
+ std::reverse(t.begin(), t.end());
+ return t;
+ }
+
+ gr_complex
+ fir_filter_with_buffer_ccf::filter(gr_complex input)
+ {
+ d_buffer[d_idx] = input;
+ d_buffer[d_idx+ntaps()] = input;
+
+ d_idx++;
+ if(d_idx >= ntaps())
+ d_idx = 0;
+
+ const gr_complex *ar = (gr_complex *)((unsigned long)(&d_buffer[d_idx]) & ~(d_align-1));
+ unsigned al = (&d_buffer[d_idx]) - ar;
+
+ volk_32fc_32f_dot_prod_32fc_a(d_output, ar,
+ d_aligned_taps[al],
+ ntaps()+al);
+ return *d_output;
+ }
+
+ gr_complex
+ fir_filter_with_buffer_ccf::filter(const gr_complex input[],
+ unsigned long dec)
+ {
+ unsigned int i;
+
+ for(i = 0; i < dec; i++) {
+ d_buffer[d_idx] = input[i];
+ d_buffer[d_idx+ntaps()] = input[i];
+ d_idx++;
+ if(d_idx >= ntaps())
+ d_idx = 0;
+ }
+
+ const gr_complex *ar = (gr_complex *)((unsigned long)(&d_buffer[d_idx]) & ~(d_align-1));
+ unsigned al = (&d_buffer[d_idx]) - ar;
+
+ volk_32fc_32f_dot_prod_32fc_a(d_output, ar,
+ d_aligned_taps[al],
+ ntaps()+al);
+ return *d_output;
+ }
+
+ void
+ fir_filter_with_buffer_ccf::filterN(gr_complex output[],
+ const gr_complex input[],
+ unsigned long n)
+ {
+ for(unsigned long i = 0; i < n; i++) {
+ output[i] = filter(input[i]);
+ }
+ }
+
+ void
+ fir_filter_with_buffer_ccf::filterNdec(gr_complex output[],
+ const gr_complex input[],
+ unsigned long n,
+ unsigned long decimate)
+ {
+ unsigned long j = 0;
+ for(unsigned long i = 0; i < n; i++) {
+ output[i] = filter(&input[j], decimate);
+ j += decimate;
+ }
+ }
+
+
+ } /* namespace kernel */
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/firdes.cc b/gr-filter/lib/firdes.cc
new file mode 100644
index 0000000000..5c3320d71a
--- /dev/null
+++ b/gr-filter/lib/firdes.cc
@@ -0,0 +1,855 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2007,2008,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <filter/firdes.h>
+#include <stdexcept>
+
+using std::vector;
+
+namespace gr {
+ namespace filter {
+
+#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>
+ firdes::low_pass_2(double gain,
+ double sampling_freq, // Hz
+ double cutoff_freq, // Hz BEGINNING of transition band
+ double transition_width, // Hz width of transition band
+ double attenuation_dB, // attenuation dB
+ win_type window_type,
+ double beta) // used only with Kaiser
+ {
+ sanity_check_1f(sampling_freq, cutoff_freq, transition_width);
+
+ int ntaps = compute_ntaps_windes(sampling_freq,
+ transition_width,
+ attenuation_dB);
+
+ // construct the truncated ideal impulse response
+ // [sin(x)/x for the low pass case]
+
+ vector<float> taps(ntaps);
+ vector<float> w = window(window_type, ntaps, beta);
+
+ int M = (ntaps - 1) / 2;
+ double fwT0 = 2 * M_PI * cutoff_freq / sampling_freq;
+ for(int n = -M; n <= M; n++) {
+ if (n == 0)
+ taps[n + M] = fwT0 / M_PI * w[n + M];
+ else {
+ // a little algebra gets this into the more familiar sin(x)/x form
+ taps[n + M] = sin(n * fwT0) / (n * M_PI) * w[n + M];
+ }
+ }
+
+ // find the factor to normalize the gain, fmax.
+ // For low-pass, gain @ zero freq = 1.0
+
+ double fmax = taps[0 + M];
+ for(int n = 1; n <= M; n++)
+ fmax += 2 * taps[n + M];
+
+ gain /= fmax; // normalize
+
+ for(int i = 0; i < ntaps; i++)
+ taps[i] *= gain;
+
+ return taps;
+ }
+
+ vector<float>
+ 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>
+ firdes::high_pass_2(double gain,
+ double sampling_freq,
+ double cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ double attenuation_dB, // attenuation dB
+ win_type window_type,
+ double beta) // used only with Kaiser
+ {
+ sanity_check_1f(sampling_freq, cutoff_freq, transition_width);
+
+ int ntaps = compute_ntaps_windes(sampling_freq,
+ transition_width,
+ attenuation_dB);
+
+ // construct the truncated ideal impulse response times the window function
+
+ vector<float> taps(ntaps);
+ vector<float> w = window(window_type, ntaps, beta);
+
+ int M = (ntaps - 1) / 2;
+ double fwT0 = 2 * M_PI * cutoff_freq / sampling_freq;
+
+ for(int n = -M; n <= M; n++) {
+ if(n == 0)
+ taps[n + M] = (1 - (fwT0 / M_PI)) * w[n + M];
+ else {
+ // a little algebra gets this into the more familiar sin(x)/x form
+ taps[n + M] = -sin(n * fwT0) / (n * M_PI) * w[n + M];
+ }
+ }
+
+ // find the factor to normalize the gain, fmax.
+ // For high-pass, gain @ fs/2 freq = 1.0
+
+ double fmax = taps[0 + M];
+ for(int n = 1; n <= M; n++)
+ fmax += 2 * taps[n + M] * cos(n * M_PI);
+
+ gain /= fmax; // normalize
+
+ for(int i = 0; i < ntaps; i++)
+ taps[i] *= gain;
+
+ return taps;
+ }
+
+
+ vector<float>
+ 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>
+ firdes::band_pass_2(double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz center of transition band
+ double high_cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ double attenuation_dB, // attenuation dB
+ win_type window_type,
+ double beta) // used only with Kaiser
+ {
+ sanity_check_2f(sampling_freq,
+ low_cutoff_freq,
+ high_cutoff_freq, transition_width);
+
+ int ntaps = compute_ntaps_windes(sampling_freq,
+ transition_width,
+ attenuation_dB);
+
+ vector<float> taps(ntaps);
+ vector<float> w = window(window_type, ntaps, beta);
+
+ int M = (ntaps - 1) / 2;
+ double fwT0 = 2 * M_PI * low_cutoff_freq / sampling_freq;
+ double fwT1 = 2 * M_PI * high_cutoff_freq / sampling_freq;
+
+ for(int n = -M; n <= M; n++) {
+ if (n == 0)
+ taps[n + M] = (fwT1 - fwT0) / M_PI * w[n + M];
+ else {
+ taps[n + M] = (sin(n * fwT1) - sin(n * fwT0)) / (n * M_PI) * w[n + M];
+ }
+ }
+
+ // find the factor to normalize the gain, fmax.
+ // For band-pass, gain @ center freq = 1.0
+
+ double fmax = taps[0 + M];
+ for(int n = 1; n <= M; n++)
+ fmax += 2 * taps[n + M] * cos(n * (fwT0 + fwT1) * 0.5);
+
+ gain /= fmax; // normalize
+
+ for(int i = 0; i < ntaps; i++)
+ taps[i] *= gain;
+
+ return taps;
+ }
+
+
+ vector<float>
+ 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>
+ firdes::complex_band_pass_2(double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz center of transition band
+ double high_cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ double attenuation_dB, // attenuation dB
+ win_type window_type,
+ double beta) // used only with Kaiser
+ {
+ sanity_check_2f_c(sampling_freq,
+ low_cutoff_freq,
+ high_cutoff_freq,
+ transition_width);
+
+ int ntaps = compute_ntaps_windes(sampling_freq,
+ transition_width,
+ attenuation_dB);
+
+ vector<gr_complex> taps(ntaps);
+ vector<float> lptaps(ntaps);
+ vector<float> w = window(window_type, ntaps, beta);
+
+ lptaps = low_pass_2(gain, sampling_freq,
+ (high_cutoff_freq - low_cutoff_freq)/2,
+ transition_width, attenuation_dB,
+ window_type, beta);
+
+ gr_complex *optr = &taps[0];
+ float *iptr = &lptaps[0];
+ float freq = M_PI * (high_cutoff_freq + low_cutoff_freq)/sampling_freq;
+ float phase = 0;
+ if (lptaps.size() & 01) {
+ phase = - freq * ( lptaps.size() >> 1 );
+ }
+ else
+ phase = - freq/2.0 * ((1 + 2*lptaps.size()) >> 1);
+
+ for(unsigned int i = 0; i < lptaps.size(); i++) {
+ *optr++ = gr_complex(*iptr * cos(phase), *iptr * sin(phase));
+ iptr++, phase += freq;
+ }
+
+ return taps;
+ }
+
+
+ vector<gr_complex>
+ 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>
+ firdes::band_reject_2(double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz center of transition band
+ double high_cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ double attenuation_dB, // attenuation dB
+ win_type window_type,
+ double beta) // used only with Kaiser
+ {
+ sanity_check_2f(sampling_freq,
+ low_cutoff_freq,
+ high_cutoff_freq,
+ transition_width);
+
+ int ntaps = compute_ntaps_windes(sampling_freq,
+ transition_width,
+ attenuation_dB);
+
+ // construct the truncated ideal impulse response times the window function
+
+ vector<float> taps(ntaps);
+ vector<float> w = window(window_type, ntaps, beta);
+
+ int M = (ntaps - 1) / 2;
+ double fwT0 = 2 * M_PI * low_cutoff_freq / sampling_freq;
+ double fwT1 = 2 * M_PI * high_cutoff_freq / sampling_freq;
+
+ for(int n = -M; n <= M; n++) {
+ if (n == 0)
+ taps[n + M] = 1.0 + ((fwT0 - fwT1) / M_PI * w[n + M]);
+ else {
+ taps[n + M] = (sin(n * fwT0) - sin(n * fwT1)) / (n * M_PI) * w[n + M];
+ }
+ }
+
+ // find the factor to normalize the gain, fmax.
+ // For band-reject, gain @ zero freq = 1.0
+
+ double fmax = taps[0 + M];
+ for(int n = 1; n <= M; n++)
+ fmax += 2 * taps[n + M];
+
+ gain /= fmax; // normalize
+
+ for(int i = 0; i < ntaps; i++)
+ taps[i] *= gain;
+
+ return taps;
+ }
+
+ vector<float>
+ 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>
+ 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>
+ firdes::gaussian(double gain,
+ double spb,
+ double bt,
+ int ntaps)
+ {
+ vector<float> taps(ntaps);
+ double scale = 0;
+ double dt = 1.0/spb;
+ double s = 1.0/(sqrt(log(2.0)) / (2*M_PI*bt));
+ double t0 = -0.5 * ntaps;
+ double ts;
+ for(int i=0;i<ntaps;i++) {
+ t0++;
+ ts = s*dt*t0;
+ taps[i] = exp(-0.5*ts*ts);
+ scale += taps[i];
+ }
+ for(int i=0;i<ntaps;i++)
+ taps[i] = taps[i] / scale * gain;
+
+ return taps;
+ }
+
+
+ //
+ // Root Raised Cosine
+ //
+
+ vector<float>
+ 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
+ firdes::compute_ntaps_windes(double sampling_freq,
+ double transition_width, // this is frequency, not relative frequency
+ double attenuation_dB)
+ {
+ // Based on formula from Multirate Signal Processing for
+ // Communications Systems, fredric j harris
+ int ntaps = (int)(attenuation_dB*sampling_freq/(22.0*transition_width));
+ if ((ntaps & 1) == 0) // if even...
+ ntaps++; // ...make odd
+ return ntaps;
+ }
+
+ int
+ 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
+ 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>
+ firdes::window (win_type type, int ntaps, double beta)
+ {
+ vector<float> taps(ntaps);
+ int M = ntaps - 1; // filter order
+
+ switch (type) {
+ case WIN_RECTANGULAR:
+ for(int n = 0; n < ntaps; n++)
+ taps[n] = 1;
+
+ case WIN_HAMMING:
+ for(int n = 0; n < ntaps; n++)
+ taps[n] = 0.54 - 0.46 * cos((2 * M_PI * n) / M);
+ break;
+
+ case WIN_HANN:
+ for(int n = 0; n < ntaps; n++)
+ taps[n] = 0.5 - 0.5 * cos((2 * M_PI * n) / M);
+ break;
+
+ case WIN_BLACKMAN:
+ for(int n = 0; n < ntaps; n++)
+ taps[n] = 0.42 - 0.50 * cos((2*M_PI * n) / (M-1))
+ - 0.08 * cos((4*M_PI * n) / (M-1));
+ break;
+
+ case WIN_BLACKMAN_hARRIS:
+ for(int n = -ntaps/2; n < ntaps/2; n++)
+ taps[n+ntaps/2] = 0.35875 + 0.48829*cos((2*M_PI * n) / (float)M) +
+ 0.14128*cos((4*M_PI * n) / (float)M) + 0.01168*cos((6*M_PI * n) / (float)M);
+ break;
+
+ 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;
+
+ default:
+ throw std::out_of_range("firdes:window: type out of range");
+ }
+
+ return taps;
+ }
+
+ void
+ firdes::sanity_check_1f(double sampling_freq,
+ double fa, // cutoff freq
+ double transition_width)
+ {
+ if(sampling_freq <= 0.0)
+ throw std::out_of_range("firdes check failed: sampling_freq > 0");
+
+ if(fa <= 0.0 || fa > sampling_freq / 2)
+ throw std::out_of_range("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
+ 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("firdes check failed: sampling_freq > 0");
+
+ if (fa <= 0.0 || fa > sampling_freq / 2)
+ throw std::out_of_range("firdes check failed: 0 < fa <= sampling_freq / 2");
+
+ if (fb <= 0.0 || fb > sampling_freq / 2)
+ throw std::out_of_range("firdes check failed: 0 < fb <= sampling_freq / 2");
+
+ if (fa > fb)
+ throw std::out_of_range("firdes check failed: fa <= fb");
+
+ if (transition_width <= 0)
+ throw std::out_of_range("firdes check failed: transition_width > 0");
+ }
+
+ void
+ 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("firdes check failed: sampling_freq > 0");
+
+ if(fa < -sampling_freq / 2 || fa > sampling_freq / 2)
+ throw std::out_of_range("firdes check failed: 0 < fa <= sampling_freq / 2");
+
+ if(fb < -sampling_freq / 2 || fb > sampling_freq / 2)
+ throw std::out_of_range("firdes check failed: 0 < fb <= sampling_freq / 2");
+
+ if(fa > fb)
+ throw std::out_of_range("firdes check failed: fa <= fb");
+
+ if(transition_width <= 0)
+ throw std::out_of_range("firdes check failed: transition_width > 0");
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/fractional_interpolator_cc_impl.cc b/gr-filter/lib/fractional_interpolator_cc_impl.cc
new file mode 100644
index 0000000000..8fd89f437f
--- /dev/null
+++ b/gr-filter/lib/fractional_interpolator_cc_impl.cc
@@ -0,0 +1,125 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_io_signature.h>
+#include "fractional_interpolator_cc_impl.h"
+#include <stdexcept>
+
+namespace gr {
+ namespace filter {
+
+ fractional_interpolator_cc::sptr
+ fractional_interpolator_cc::make(float phase_shift, float interp_ratio)
+ {
+ return gnuradio::get_initial_sptr(
+ new fractional_interpolator_cc_impl(phase_shift, interp_ratio));
+ }
+
+ fractional_interpolator_cc_impl::fractional_interpolator_cc_impl
+ (float phase_shift, float interp_ratio)
+ : gr_block("fractional_interpolator_cc",
+ gr_make_io_signature(1, 1, sizeof(gr_complex)),
+ gr_make_io_signature(1, 1, sizeof(gr_complex))),
+ d_mu (phase_shift), d_mu_inc (interp_ratio),
+ d_interp(new mmse_fir_interpolator_cc())
+ {
+ if(interp_ratio <= 0)
+ throw std::out_of_range("interpolation ratio must be > 0");
+ if(phase_shift < 0 || phase_shift > 1)
+ throw std::out_of_range("phase shift ratio must be > 0 and < 1");
+
+ set_relative_rate(1.0 / interp_ratio);
+ }
+
+ fractional_interpolator_cc_impl::~fractional_interpolator_cc_impl()
+ {
+ delete d_interp;
+ }
+
+ void
+ fractional_interpolator_cc_impl::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
+ fractional_interpolator_cc_impl::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const gr_complex *in = (const gr_complex*)input_items[0];
+ gr_complex *out = (gr_complex*)output_items[0];
+
+ int ii = 0; // input index
+ int oo = 0; // output index
+
+ while(oo < noutput_items) {
+ out[oo++] = d_interp->interpolate(&in[ii], d_mu);
+
+ double s = d_mu + d_mu_inc;
+ double f = floor(s);
+ int incr = (int)f;
+ d_mu = s - f;
+ ii += incr;
+ }
+
+ consume_each(ii);
+
+ return noutput_items;
+ }
+
+ float
+ fractional_interpolator_cc_impl::mu() const
+ {
+ return d_mu;
+ }
+
+ float
+ fractional_interpolator_cc_impl::interp_ratio() const
+ {
+ return d_mu_inc;
+ }
+
+ void
+ fractional_interpolator_cc_impl::set_mu(float mu)
+ {
+ d_mu = mu;
+ }
+
+ void
+ fractional_interpolator_cc_impl::set_interp_ratio(float interp_ratio)
+ {
+ d_mu_inc = interp_ratio;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/fractional_interpolator_cc_impl.h b/gr-filter/lib/fractional_interpolator_cc_impl.h
new file mode 100644
index 0000000000..cb42186038
--- /dev/null
+++ b/gr-filter/lib/fractional_interpolator_cc_impl.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_FRACTIONAL_INTERPOLATOR_CC_IMPL_H
+#define INCLUDED_FRACTIONAL_INTERPOLATOR_CC_IMPL_H
+
+#include <filter/fractional_interpolator_cc.h>
+#include <filter/mmse_fir_interpolator_cc.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API fractional_interpolator_cc_impl
+ : public fractional_interpolator_cc
+ {
+ private:
+ float d_mu;
+ float d_mu_inc;
+ mmse_fir_interpolator_cc *d_interp;
+
+ public:
+ fractional_interpolator_cc_impl(float phase_shift,
+ float interp_ratio);
+ ~fractional_interpolator_cc_impl();
+
+ 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;
+ float interp_ratio() const;
+ void set_mu(float mu);
+ void set_interp_ratio(float interp_ratio);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FRACTIONAL_INTERPOLATOR_CC_IMPL_H */
diff --git a/gr-filter/lib/fractional_interpolator_ff_impl.cc b/gr-filter/lib/fractional_interpolator_ff_impl.cc
new file mode 100644
index 0000000000..6b35dc1061
--- /dev/null
+++ b/gr-filter/lib/fractional_interpolator_ff_impl.cc
@@ -0,0 +1,125 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_io_signature.h>
+#include "fractional_interpolator_ff_impl.h"
+#include <stdexcept>
+
+namespace gr {
+ namespace filter {
+
+ fractional_interpolator_ff::sptr
+ fractional_interpolator_ff::make(float phase_shift, float interp_ratio)
+ {
+ return gnuradio::get_initial_sptr(
+ new fractional_interpolator_ff_impl(phase_shift, interp_ratio));
+ }
+
+ fractional_interpolator_ff_impl::fractional_interpolator_ff_impl
+ (float phase_shift, float interp_ratio)
+ : gr_block("fractional_interpolator_ff",
+ gr_make_io_signature(1, 1, sizeof(float)),
+ gr_make_io_signature(1, 1, sizeof(float))),
+ d_mu (phase_shift), d_mu_inc (interp_ratio),
+ d_interp(new mmse_fir_interpolator_ff())
+ {
+ 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);
+ }
+
+ fractional_interpolator_ff_impl::~fractional_interpolator_ff_impl()
+ {
+ delete d_interp;
+ }
+
+ void
+ fractional_interpolator_ff_impl::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
+ fractional_interpolator_ff_impl::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const float *in = (const float*)input_items[0];
+ float *out = (float*)output_items[0];
+
+ int ii = 0; // input index
+ int oo = 0; // output index
+
+ while(oo < noutput_items) {
+ out[oo++] = d_interp->interpolate(&in[ii], d_mu);
+
+ double s = d_mu + d_mu_inc;
+ double f = floor(s);
+ int incr = (int)f;
+ d_mu = s - f;
+ ii += incr;
+ }
+
+ consume_each(ii);
+
+ return noutput_items;
+ }
+
+ float
+ fractional_interpolator_ff_impl::mu() const
+ {
+ return d_mu;
+ }
+
+ float
+ fractional_interpolator_ff_impl::interp_ratio() const
+ {
+ return d_mu_inc;
+ }
+
+ void
+ fractional_interpolator_ff_impl::set_mu(float mu)
+ {
+ d_mu = mu;
+ }
+
+ void
+ fractional_interpolator_ff_impl::set_interp_ratio(float interp_ratio)
+ {
+ d_mu_inc = interp_ratio;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/fractional_interpolator_ff_impl.h b/gr-filter/lib/fractional_interpolator_ff_impl.h
new file mode 100644
index 0000000000..d31385cc49
--- /dev/null
+++ b/gr-filter/lib/fractional_interpolator_ff_impl.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_FRACTIONAL_INTERPOLATOR_FF_IMPL_H
+#define INCLUDED_FRACTIONAL_INTERPOLATOR_FF_IMPL_H
+
+#include <filter/fractional_interpolator_ff.h>
+#include <filter/mmse_fir_interpolator_ff.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API fractional_interpolator_ff_impl
+ : public fractional_interpolator_ff
+ {
+ private:
+ float d_mu;
+ float d_mu_inc;
+ mmse_fir_interpolator_ff *d_interp;
+
+ public:
+ fractional_interpolator_ff_impl(float phase_shift,
+ float interp_ratio);
+ ~fractional_interpolator_ff_impl();
+
+ 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;
+ float interp_ratio() const;
+ void set_mu(float mu);
+ void set_interp_ratio(float interp_ratio);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FRACTIONAL_INTERPOLATOR_FF_IMPL_H */
diff --git a/gr-filter/lib/freq_xlating_fir_filter_XXX_impl.cc.t b/gr-filter/lib/freq_xlating_fir_filter_XXX_impl.cc.t
new file mode 100644
index 0000000000..a59fa12b36
--- /dev/null
+++ b/gr-filter/lib/freq_xlating_fir_filter_XXX_impl.cc.t
@@ -0,0 +1,143 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * WARNING: This file is automatically generated by cmake.
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "@IMPL_NAME@.h"
+#include <gr_io_signature.h>
+#include <volk/volk.h>
+
+namespace gr {
+ namespace filter {
+
+ @BASE_NAME@::sptr
+ @BASE_NAME@::make(int decimation,
+ const std::vector<@TAP_TYPE@> &taps,
+ double center_freq,
+ double sampling_freq)
+ {
+ return gnuradio::get_initial_sptr(new @IMPL_NAME@
+ (decimation, taps,
+ center_freq,
+ sampling_freq));
+ }
+
+ @IMPL_NAME@::@IMPL_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 = new kernel::@CFIR_TYPE@(decimation, dummy_taps);
+
+ set_history(d_proto_taps.size());
+ build_composite_fir();
+ }
+
+ @IMPL_NAME@::~@IMPL_NAME@()
+ {
+ delete d_composite_fir;
+ }
+
+ void
+ @IMPL_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));
+ }
+
+ std::reverse(ctaps.begin(), ctaps.end());
+ d_composite_fir->set_taps(ctaps);
+ d_r.set_phase_incr(exp(gr_complex(0, fwT0 * decimation())));
+ }
+
+ void
+ @IMPL_NAME@::set_center_freq(double center_freq)
+ {
+ d_center_freq = center_freq;
+ d_updated = true;
+ }
+
+ double
+ @IMPL_NAME@::center_freq() const
+ {
+ return d_center_freq;
+ }
+
+ void
+ @IMPL_NAME@::set_taps(const std::vector<@TAP_TYPE@> &taps)
+ {
+ d_proto_taps = taps;
+ d_updated = true;
+ }
+
+ std::vector<@TAP_TYPE@>
+ @IMPL_NAME@::taps() const
+ {
+ return d_proto_taps;
+ }
+
+ int
+ @IMPL_NAME@::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ @I_TYPE@ *in = (@I_TYPE@ *)input_items[0];
+ @O_TYPE@ *out = (@O_TYPE@ *)output_items[0];
+
+ // rebuild composite FIR if the center freq has changed
+ if(d_updated) {
+ set_history(d_proto_taps.size());
+ build_composite_fir();
+ d_updated = false;
+ return 0; // history requirements may have changed.
+ }
+
+ unsigned j = 0;
+ for (int i = 0; i < noutput_items; i++){
+ out[i] = d_r.rotate(d_composite_fir->filter(&in[j]));
+ j += decimation();
+ }
+
+ return noutput_items;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
+
diff --git a/gr-filter/lib/freq_xlating_fir_filter_XXX_impl.h.t b/gr-filter/lib/freq_xlating_fir_filter_XXX_impl.h.t
new file mode 100644
index 0000000000..0cf976d582
--- /dev/null
+++ b/gr-filter/lib/freq_xlating_fir_filter_XXX_impl.h.t
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2004,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * WARNING: This file is automatically generated by cmake.
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <filter/api.h>
+#include <filter/fir_filter.h>
+#include <filter/@BASE_NAME@.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API @IMPL_NAME@ : public @BASE_NAME@
+ {
+ protected:
+ std::vector<@TAP_TYPE@> d_proto_taps;
+ kernel::@CFIR_TYPE@ *d_composite_fir;
+ gr_rotator d_r;
+ double d_center_freq;
+ double d_sampling_freq;
+ bool d_updated;
+
+ virtual void build_composite_fir();
+ public:
+
+ @IMPL_NAME@(int decimation,
+ const std::vector<@TAP_TYPE@> &taps,
+ double center_freq,
+ double sampling_freq);
+ virtual ~@IMPL_NAME@();
+
+ void set_center_freq(double center_freq);
+ double center_freq() const;
+
+ void set_taps(const std::vector<@TAP_TYPE@> &taps);
+ std::vector<@TAP_TYPE@> taps() const;
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* @GUARD_NAME@ */
diff --git a/gr-filter/lib/hilbert_fc_impl.cc b/gr-filter/lib/hilbert_fc_impl.cc
new file mode 100644
index 0000000000..52b2dabae9
--- /dev/null
+++ b/gr-filter/lib/hilbert_fc_impl.cc
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "hilbert_fc_impl.h"
+#include <filter/firdes.h>
+#include <gr_io_signature.h>
+#include <volk/volk.h>
+
+namespace gr {
+ namespace filter {
+
+ hilbert_fc::sptr hilbert_fc::make(unsigned int ntaps)
+ {
+ return gnuradio::get_initial_sptr(new hilbert_fc_impl(ntaps));
+ }
+
+ hilbert_fc_impl::hilbert_fc_impl(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 = new kernel::fir_filter_fff(1, firdes::hilbert(d_ntaps));
+ set_history (d_ntaps);
+
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(float);
+ set_alignment(std::max(1, alignment_multiple));
+ }
+
+ hilbert_fc_impl::~hilbert_fc_impl()
+ {
+ delete d_hilb;
+ }
+
+ int
+ hilbert_fc_impl::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;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/hilbert_fc_impl.h b/gr-filter/lib/hilbert_fc_impl.h
new file mode 100644
index 0000000000..d2b41b5732
--- /dev/null
+++ b/gr-filter/lib/hilbert_fc_impl.h
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_FILTER_HILBERT_FC_IMPL_H
+#define INCLUDED_FILTER_HILBERT_FC_IMPL_H
+
+#include <filter/hilbert_fc.h>
+#include <filter/fir_filter.h>
+#include <gr_types.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API hilbert_fc_impl : public hilbert_fc
+ {
+ private:
+ unsigned int d_ntaps;
+ kernel::fir_filter_fff *d_hilb;
+
+ public:
+ hilbert_fc_impl(unsigned int ntaps);
+
+ ~hilbert_fc_impl();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_HILBERT_FC_IMPL_H */
diff --git a/gr-filter/lib/iir_filter_ffd_impl.cc b/gr-filter/lib/iir_filter_ffd_impl.cc
new file mode 100644
index 0000000000..24bfad1908
--- /dev/null
+++ b/gr-filter/lib/iir_filter_ffd_impl.cc
@@ -0,0 +1,85 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "iir_filter_ffd_impl.h"
+#include <gr_io_signature.h>
+
+namespace gr {
+ namespace filter {
+
+ iir_filter_ffd::sptr
+ iir_filter_ffd::make(const std::vector<double> &fftaps,
+ const std::vector<double> &fbtaps)
+ {
+ return gnuradio::get_initial_sptr(new iir_filter_ffd_impl(fftaps, fbtaps));
+ }
+
+ iir_filter_ffd_impl::iir_filter_ffd_impl(const std::vector<double> &fftaps,
+ const std::vector<double> &fbtaps)
+
+ : gr_sync_block("iir_filter_ffd",
+ gr_make_io_signature(1, 1, sizeof (float)),
+ gr_make_io_signature(1, 1, sizeof (float))),
+ d_updated(false)
+ {
+ d_iir = new kernel::iir_filter<float,float,double>(fftaps, fbtaps);
+ //d_iir = new gri_iir<float,float,double>(fftaps, fbtaps);
+ }
+
+ iir_filter_ffd_impl::~iir_filter_ffd_impl()
+ {
+ delete d_iir;
+ }
+
+ void
+ iir_filter_ffd_impl::set_taps(const std::vector<double> &fftaps,
+ const std::vector<double> &fbtaps)
+ {
+ d_new_fftaps = fftaps;
+ d_new_fbtaps = fbtaps;
+ d_updated = true;
+ }
+
+ int
+ iir_filter_ffd_impl::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const float *in = (const float*)input_items[0];
+ float *out = (float*)output_items[0];
+
+ if(d_updated) {
+ d_iir->set_taps(d_new_fftaps, d_new_fbtaps);
+ d_updated = false;
+ }
+
+ d_iir->filter_n(out, in, noutput_items);
+ return noutput_items;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
diff --git a/gr-filter/lib/iir_filter_ffd_impl.h b/gr-filter/lib/iir_filter_ffd_impl.h
new file mode 100644
index 0000000000..45aab6c227
--- /dev/null
+++ b/gr-filter/lib/iir_filter_ffd_impl.h
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_IIR_FILTER_FFD_IMPL_H
+#define INCLUDED_IIR_FILTER_FFD_IMPL_H
+
+#include <filter/iir_filter.h>
+#include <filter/iir_filter_ffd.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API iir_filter_ffd_impl : public iir_filter_ffd
+ {
+ private:
+ bool d_updated;
+ kernel::iir_filter<float,float,double> *d_iir;
+ std::vector<double> d_new_fftaps;
+ std::vector<double> d_new_fbtaps;
+
+ public:
+ iir_filter_ffd_impl(const std::vector<double> &fftaps,
+ const std::vector<double> &fbtaps);
+ ~iir_filter_ffd_impl();
+
+ void set_taps(const std::vector<double> &fftaps,
+ const std::vector<double> &fbtaps);
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_IIR_FILTER_FFD_IMPL_H */
diff --git a/gr-filter/lib/interp_fir_filter_XXX_impl.cc.t b/gr-filter/lib/interp_fir_filter_XXX_impl.cc.t
new file mode 100644
index 0000000000..c9127d7379
--- /dev/null
+++ b/gr-filter/lib/interp_fir_filter_XXX_impl.cc.t
@@ -0,0 +1,151 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/* @WARNING@ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "@IMPL_NAME@.h"
+#include <gr_io_signature.h>
+#include <volk/volk.h>
+#include <stdexcept>
+
+namespace gr {
+ namespace filter {
+
+ @BASE_NAME@::sptr
+ @BASE_NAME@::make(unsigned interpolation,
+ const std::vector<@TAP_TYPE@> &taps)
+ {
+ return gnuradio::get_initial_sptr(new @IMPL_NAME@
+ (interpolation, taps));
+ }
+
+ @IMPL_NAME@::@IMPL_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("@IMPL_NAME@: interpolation must be > 0\n");
+ }
+
+ std::vector<@TAP_TYPE@> dummy_taps;
+
+ for(unsigned i = 0; i < interpolation; i++) {
+ d_firs[i] = new kernel::@FIR_TYPE@(1, dummy_taps);
+ }
+
+ set_taps(taps);
+ install_taps(d_new_taps);
+ }
+
+ @IMPL_NAME@::~@IMPL_NAME@()
+ {
+ for(unsigned i = 0; i < interpolation(); i++) {
+ delete d_firs[i];
+ }
+ }
+
+ void
+ @IMPL_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);
+ }
+ }
+
+ if(d_new_taps.size() % interpolation() != 0) {
+ throw std::runtime_error("@IMPL_NAME@: error setting interpolator taps.\n");
+ }
+ }
+
+ void
+ @IMPL_NAME@::install_taps(const std::vector<@TAP_TYPE@> &taps)
+ {
+ unsigned nfilters = interpolation();
+ int nt = taps.size() / nfilters;
+
+ std::vector< std::vector <@TAP_TYPE@> > xtaps(nfilters);
+
+ for(unsigned n = 0; n < nfilters; n++) {
+ xtaps[n].resize (nt);
+ }
+
+ for(size_t i = 0; i < taps.size(); i++) {
+ xtaps[i % nfilters][i / nfilters] = taps[i];
+ }
+
+ for(unsigned n = 0; n < nfilters; n++) {
+ d_firs[n]->set_taps (xtaps[n]);
+ }
+
+ set_history(nt);
+ d_updated = false;
+ }
+
+ std::vector<@TAP_TYPE@>
+ @IMPL_NAME@::taps() const
+ {
+ return d_new_taps;
+ }
+
+ int
+ @NAME@::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ 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;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/interp_fir_filter_XXX_impl.h.t b/gr-filter/lib/interp_fir_filter_XXX_impl.h.t
new file mode 100644
index 0000000000..e505fca698
--- /dev/null
+++ b/gr-filter/lib/interp_fir_filter_XXX_impl.h.t
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/* @WARNING@ */
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <filter/api.h>
+#include <filter/fir_filter.h>
+#include <filter/@BASE_NAME@.h>
+#include <vector>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API @IMPL_NAME@ : public @BASE_NAME@
+ {
+ private:
+ bool d_updated;
+ std::vector<kernel::@FIR_TYPE@ *> d_firs;
+ std::vector<@TAP_TYPE@> d_new_taps;
+
+ void install_taps(const std::vector<@TAP_TYPE@> &taps);
+
+ public:
+ @IMPL_NAME@(unsigned interpolation,
+ const std::vector<@TAP_TYPE@> &taps);
+
+ ~@IMPL_NAME@();
+
+ void set_taps(const std::vector<@TAP_TYPE@> &taps);
+ std::vector<@TAP_TYPE@> taps() const;
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* @GUARD_NAME@ */
diff --git a/gr-filter/lib/mmse_fir_interpolator_cc.cc b/gr-filter/lib/mmse_fir_interpolator_cc.cc
new file mode 100644
index 0000000000..8af1fb39a6
--- /dev/null
+++ b/gr-filter/lib/mmse_fir_interpolator_cc.cc
@@ -0,0 +1,77 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <filter/mmse_fir_interpolator_cc.h>
+#include <filter/interpolator_taps.h>
+#include <stdexcept>
+
+namespace gr {
+ namespace filter {
+
+ mmse_fir_interpolator_cc::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] = new kernel::fir_filter_ccf(1, t);
+ }
+ }
+
+ mmse_fir_interpolator_cc::~mmse_fir_interpolator_cc()
+ {
+ for(int i = 0; i < NSTEPS + 1; i++)
+ delete filters[i];
+ }
+
+ unsigned
+ mmse_fir_interpolator_cc::ntaps() const
+ {
+ return NTAPS;
+ }
+
+ unsigned
+ mmse_fir_interpolator_cc::nsteps() const
+ {
+ return NSTEPS;
+ }
+
+ gr_complex
+ mmse_fir_interpolator_cc::interpolate(const gr_complex input[],
+ float mu) const
+ {
+ int imu = (int)rint(mu * NSTEPS);
+
+ if((imu < 0) || (imu > NSTEPS)) {
+ throw std::runtime_error("mmse_fir_interpolator_cc: imu out of bounds.\n");
+ }
+
+ gr_complex r = filters[imu]->filter(input);
+ return r;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/mmse_fir_interpolator_ff.cc b/gr-filter/lib/mmse_fir_interpolator_ff.cc
new file mode 100644
index 0000000000..ff2c4dd873
--- /dev/null
+++ b/gr-filter/lib/mmse_fir_interpolator_ff.cc
@@ -0,0 +1,77 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <filter/mmse_fir_interpolator_ff.h>
+#include <filter/interpolator_taps.h>
+#include <stdexcept>
+
+namespace gr {
+ namespace filter {
+
+ mmse_fir_interpolator_ff::mmse_fir_interpolator_ff()
+ {
+ filters.resize(NSTEPS + 1);
+
+ for(int i = 0; i < NSTEPS + 1; i++) {
+ std::vector<float> t(&taps[i][0], &taps[i][NTAPS]);
+ filters[i] = new kernel::fir_filter_fff(1, t);
+ }
+ }
+
+ mmse_fir_interpolator_ff::~mmse_fir_interpolator_ff()
+ {
+ for(int i = 0; i < NSTEPS + 1; i++)
+ delete filters[i];
+ }
+
+ unsigned
+ mmse_fir_interpolator_ff::ntaps() const
+ {
+ return NTAPS;
+ }
+
+ unsigned
+ mmse_fir_interpolator_ff::nsteps() const
+ {
+ return NSTEPS;
+ }
+
+ float
+ mmse_fir_interpolator_ff::interpolate(const float input[],
+ float mu) const
+ {
+ int imu = (int)rint(mu * NSTEPS);
+
+ if((imu < 0) || (imu > NSTEPS)) {
+ throw std::runtime_error("mmse_fir_interpolator_ff: imu out of bounds.\n");
+ }
+
+ float r = filters[imu]->filter(input);
+ return r;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/pfb_arb_resampler_ccf_impl.cc b/gr-filter/lib/pfb_arb_resampler_ccf_impl.cc
new file mode 100644
index 0000000000..5480366de2
--- /dev/null
+++ b/gr-filter/lib/pfb_arb_resampler_ccf_impl.cc
@@ -0,0 +1,258 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pfb_arb_resampler_ccf_impl.h"
+#include <gr_io_signature.h>
+#include <cstdio>
+
+namespace gr {
+ namespace filter {
+
+ pfb_arb_resampler_ccf::sptr
+ pfb_arb_resampler_ccf::make(float rate,
+ const std::vector<float> &taps,
+ unsigned int filter_size)
+ {
+ return gnuradio::get_initial_sptr
+ (new pfb_arb_resampler_ccf_impl(rate, taps, filter_size));
+ }
+
+
+ pfb_arb_resampler_ccf_impl::pfb_arb_resampler_ccf_impl(float rate,
+ const std::vector<float> &taps,
+ unsigned int filter_size)
+ : gr_block("pfb_arb_resampler_ccf",
+ gr_make_io_signature(1, 1, sizeof(gr_complex)),
+ gr_make_io_signature(1, 1, sizeof(gr_complex))),
+ d_updated (false)
+ {
+ d_acc = 0; // start accumulator at 0
+
+ /* The number of filters is specified by the user as the filter
+ size; this is also the interpolation rate of the filter. We
+ use it and the rate provided to determine the decimation
+ rate. This acts as a rational resampler. The flt_rate is
+ calculated as the residual between the integer decimation
+ rate and the real decimation rate and will be used to
+ determine to interpolation point of the resampling process.
+ */
+ d_int_rate = filter_size;
+ set_rate(rate);
+
+ // Store the last filter between calls to work
+ d_last_filter = 0;
+
+ d_start_index = 0;
+
+ d_filters = std::vector<kernel::fir_filter_ccf*>(d_int_rate);
+ d_diff_filters = std::vector<kernel::fir_filter_ccf*>(d_int_rate);
+
+ // Create an FIR filter for each channel and zero out the taps
+ std::vector<float> vtaps(0, d_int_rate);
+ for(unsigned int i = 0; i < d_int_rate; i++) {
+ d_filters[i] = new kernel::fir_filter_ccf(1, vtaps);
+ d_diff_filters[i] = new kernel::fir_filter_ccf(1, vtaps);
+ }
+
+ // Now, actually set the filters' taps
+ set_taps(taps);
+ d_updated = false;
+ }
+
+ pfb_arb_resampler_ccf_impl::~pfb_arb_resampler_ccf_impl()
+ {
+ for(unsigned int i = 0; i < d_int_rate; i++) {
+ delete d_filters[i];
+ delete d_diff_filters[i];
+ }
+ }
+
+ void
+ pfb_arb_resampler_ccf_impl::create_taps(const std::vector<float> &newtaps,
+ std::vector< std::vector<float> > &ourtaps,
+ std::vector<kernel::fir_filter_ccf*> &ourfilter)
+ {
+ unsigned int ntaps = newtaps.size();
+ d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_int_rate);
+
+ // Create d_numchan vectors to store each channel's taps
+ ourtaps.resize(d_int_rate);
+
+ // Make a vector of the taps plus fill it out with 0's to fill
+ // each polyphase filter with exactly d_taps_per_filter
+ std::vector<float> tmp_taps;
+ tmp_taps = newtaps;
+ while((float)(tmp_taps.size()) < d_int_rate*d_taps_per_filter) {
+ tmp_taps.push_back(0.0);
+ }
+
+ // Partition the filter
+ for(unsigned int i = 0; i < d_int_rate; i++) {
+ // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out
+ ourtaps[d_int_rate-1-i] = std::vector<float>(d_taps_per_filter, 0);
+ for(unsigned int j = 0; j < d_taps_per_filter; j++) {
+ ourtaps[d_int_rate - 1 - i][j] = tmp_taps[i + j*d_int_rate];
+ }
+
+ // Build a filter for each channel and add it's taps to it
+ ourfilter[i]->set_taps(ourtaps[d_int_rate-1-i]);
+ }
+ }
+
+ void
+ pfb_arb_resampler_ccf_impl::create_diff_taps(const std::vector<float> &newtaps,
+ std::vector<float> &difftaps)
+ {
+ // Calculate the differential taps (derivative filter) by taking the difference
+ // between two taps. Duplicate the last one to make both filters the same length.
+ float tap;
+ difftaps.clear();
+ for(unsigned int i = 0; i < newtaps.size()-1; i++) {
+ tap = newtaps[i+1] - newtaps[i];
+ difftaps.push_back(tap);
+ }
+ difftaps.push_back(tap);
+ }
+
+ void
+ pfb_arb_resampler_ccf_impl::set_taps(const std::vector<float> &taps)
+ {
+ gruel::scoped_lock guard(d_mutex);
+
+ std::vector<float> dtaps;
+ create_diff_taps(taps, dtaps);
+ create_taps(taps, d_taps, d_filters);
+ create_taps(dtaps, d_dtaps, d_diff_filters);
+ set_history(d_taps_per_filter + 1);
+ d_updated = true;
+ }
+
+ std::vector<std::vector<float> >
+ pfb_arb_resampler_ccf_impl::taps() const
+ {
+ return d_taps;
+ }
+
+ void
+ pfb_arb_resampler_ccf_impl::print_taps()
+ {
+ unsigned int i, j;
+ for(i = 0; i < d_int_rate; i++) {
+ printf("filter[%d]: [", i);
+ for(j = 0; j < d_taps_per_filter; j++) {
+ printf(" %.4e", d_taps[i][j]);
+ }
+ printf("]\n");
+ }
+ }
+
+ void
+ pfb_arb_resampler_ccf_impl::set_rate(float rate)
+ {
+ gruel::scoped_lock guard(d_mutex);
+
+ d_dec_rate = (unsigned int)floor(d_int_rate/rate);
+ d_flt_rate = (d_int_rate/rate) - d_dec_rate;
+ set_relative_rate(rate);
+ }
+
+ void
+ pfb_arb_resampler_ccf_impl::set_phase(float ph)
+ {
+ gruel::scoped_lock guard(d_mutex);
+ if((ph < 0) || (ph >= 2.0*M_PI)) {
+ throw std::runtime_error("pfb_arb_resampler_ccf: set_phase value out of bounds [0, 2pi).\n");
+ }
+
+ float ph_diff = 2.0*M_PI / (float)d_filters.size();
+ d_last_filter = static_cast<int>(ph / ph_diff);
+ }
+
+ float
+ pfb_arb_resampler_ccf_impl::phase() const
+ {
+ float ph_diff = 2.0*M_PI / static_cast<float>(d_filters.size());
+ return d_last_filter * ph_diff;
+ }
+
+ int
+ pfb_arb_resampler_ccf_impl::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ gruel::scoped_lock guard(d_mutex);
+
+ gr_complex *in = (gr_complex*)input_items[0];
+ gr_complex *out = (gr_complex*)output_items[0];
+
+ if(d_updated) {
+ d_updated = false;
+ return 0; // history requirements may have changed.
+ }
+
+ int i = 0, count = d_start_index;
+ unsigned int j;
+ gr_complex o0, o1;
+
+ // Restore the last filter position
+ j = d_last_filter;
+
+ // produce output as long as we can and there are enough input samples
+ int max_input = ninput_items[0] - (int)d_taps_per_filter;
+ while((i < noutput_items) && (count < max_input)) {
+ // start j by wrapping around mod the number of channels
+ while((j < d_int_rate) && (i < noutput_items)) {
+ // Take the current filter and derivative filter output
+ o0 = d_filters[j]->filter(&in[count]);
+ o1 = d_diff_filters[j]->filter(&in[count]);
+
+ out[i] = o0 + o1*d_acc; // linearly interpolate between samples
+ i++;
+
+ // Adjust accumulator and index into filterbank
+ d_acc += d_flt_rate;
+ j += d_dec_rate + (int)floor(d_acc);
+ d_acc = fmodf(d_acc, 1.0);
+ }
+ if(i < noutput_items) { // keep state for next entry
+ float ss = (int)(j / d_int_rate); // number of items to skip ahead by
+ count += ss; // we have fully consumed another input
+ j = j % d_int_rate; // roll filter around
+ }
+ }
+
+ // Store the current filter position and start of next sample
+ d_last_filter = j;
+ d_start_index = std::max(0, count - ninput_items[0]);
+
+ // consume all we've processed but no more than we can
+ consume_each(std::min(count, ninput_items[0]));
+ return i;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/pfb_arb_resampler_ccf_impl.h b/gr-filter/lib/pfb_arb_resampler_ccf_impl.h
new file mode 100644
index 0000000000..891e601e09
--- /dev/null
+++ b/gr-filter/lib/pfb_arb_resampler_ccf_impl.h
@@ -0,0 +1,89 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_PFB_ARB_RESAMPLER_CCF_IMPL_H
+#define INCLUDED_PFB_ARB_RESAMPLER_CCF_IMPL_H
+
+#include <filter/pfb_arb_resampler_ccf.h>
+#include <filter/fir_filter.h>
+#include <gruel/thread.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API pfb_arb_resampler_ccf_impl : public pfb_arb_resampler_ccf
+ {
+ private:
+ std::vector<kernel::fir_filter_ccf*> d_filters;
+ std::vector<kernel::fir_filter_ccf*> d_diff_filters;
+ std::vector< std::vector<float> > d_taps;
+ std::vector< std::vector<float> > d_dtaps;
+ unsigned int d_int_rate; // the number of filters (interpolation rate)
+ unsigned int d_dec_rate; // the stride through the filters (decimation rate)
+ float d_flt_rate; // residual rate for the linear interpolation
+ float d_acc;
+ unsigned int d_last_filter;
+ int d_start_index;
+ unsigned int d_taps_per_filter;
+ bool d_updated;
+ gruel::mutex d_mutex; // mutex to protect set/work access
+
+ void create_diff_taps(const std::vector<float> &newtaps,
+ std::vector<float> &difftaps);
+
+ /*!
+ * Resets the filterbank's filter taps with the new prototype filter
+ * \param newtaps (vector of floats) The prototype filter to populate the filterbank.
+ * The taps should be generated at the interpolated sampling rate.
+ * \param ourtaps (vector of floats) Reference to our internal member of holding the taps.
+ * \param ourfilter (vector of filters) Reference to our internal filter to set the taps for.
+ */
+ void create_taps(const std::vector<float> &newtaps,
+ std::vector< std::vector<float> > &ourtaps,
+ std::vector<kernel::fir_filter_ccf*> &ourfilter);
+
+ public:
+ pfb_arb_resampler_ccf_impl(float rate,
+ const std::vector<float> &taps,
+ unsigned int filter_size);
+
+ ~pfb_arb_resampler_ccf_impl();
+
+ void set_taps(const std::vector<float> &taps);
+ std::vector<std::vector<float> > taps() const;
+ void print_taps();
+ void set_rate(float rate);
+
+ void set_phase(float ph);
+ float phase() const;
+
+ int general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_PFB_ARB_RESAMPLER_CCF_IMPL_H */
diff --git a/gr-filter/lib/pfb_arb_resampler_fff_impl.cc b/gr-filter/lib/pfb_arb_resampler_fff_impl.cc
new file mode 100644
index 0000000000..6aff374fdd
--- /dev/null
+++ b/gr-filter/lib/pfb_arb_resampler_fff_impl.cc
@@ -0,0 +1,258 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009-2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pfb_arb_resampler_fff_impl.h"
+#include <gr_io_signature.h>
+#include <cstdio>
+
+namespace gr {
+ namespace filter {
+
+ pfb_arb_resampler_fff::sptr
+ pfb_arb_resampler_fff::make(float rate,
+ const std::vector<float> &taps,
+ unsigned int filter_size)
+ {
+ return gnuradio::get_initial_sptr
+ (new pfb_arb_resampler_fff_impl(rate, taps, filter_size));
+ }
+
+
+ pfb_arb_resampler_fff_impl::pfb_arb_resampler_fff_impl(float rate,
+ const std::vector<float> &taps,
+ unsigned int filter_size)
+ : gr_block("pfb_arb_resampler_fff",
+ gr_make_io_signature(1, 1, sizeof(float)),
+ gr_make_io_signature(1, 1, sizeof(float))),
+ d_updated(false)
+ {
+ d_acc = 0; // start accumulator at 0
+
+ /* The number of filters is specified by the user as the filter
+ size; this is also the interpolation rate of the filter. We
+ use it and the rate provided to determine the decimation
+ rate. This acts as a rational resampler. The flt_rate is
+ calculated as the residual between the integer decimation
+ rate and the real decimation rate and will be used to
+ determine to interpolation point of the resampling process.
+ */
+ d_int_rate = filter_size;
+ set_rate(rate);
+
+ // Store the last filter between calls to work
+ d_last_filter = 0;
+
+ d_start_index = 0;
+
+ d_filters = std::vector<kernel::fir_filter_fff*>(d_int_rate);
+ d_diff_filters = std::vector<kernel::fir_filter_fff*>(d_int_rate);
+
+ // Create an FIR filter for each channel and zero out the taps
+ std::vector<float> vtaps(0, d_int_rate);
+ for(unsigned int i = 0; i < d_int_rate; i++) {
+ d_filters[i] = new kernel::fir_filter_fff(1, vtaps);
+ d_diff_filters[i] = new kernel::fir_filter_fff(1, vtaps);
+ }
+
+ // Now, actually set the filters' taps
+ std::vector<float> dtaps;
+ create_diff_taps(taps, dtaps);
+ create_taps(taps, d_taps, d_filters);
+ create_taps(dtaps, d_dtaps, d_diff_filters);
+ }
+
+ pfb_arb_resampler_fff_impl::~pfb_arb_resampler_fff_impl()
+ {
+ for(unsigned int i = 0; i < d_int_rate; i++) {
+ delete d_filters[i];
+ delete d_diff_filters[i];
+ }
+ }
+
+ void
+ pfb_arb_resampler_fff_impl::create_taps(const std::vector<float> &newtaps,
+ std::vector< std::vector<float> > &ourtaps,
+ std::vector<kernel::fir_filter_fff*> &ourfilter)
+ {
+ unsigned int ntaps = newtaps.size();
+ d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_int_rate);
+
+ // Create d_numchan vectors to store each channel's taps
+ ourtaps.resize(d_int_rate);
+
+ // Make a vector of the taps plus fill it out with 0's to fill
+ // each polyphase filter with exactly d_taps_per_filter
+ std::vector<float> tmp_taps;
+ tmp_taps = newtaps;
+ while((float)(tmp_taps.size()) < d_int_rate*d_taps_per_filter) {
+ tmp_taps.push_back(0.0);
+ }
+
+ // Partition the filter
+ for(unsigned int i = 0; i < d_int_rate; i++) {
+ // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out
+ ourtaps[d_int_rate-1-i] = std::vector<float>(d_taps_per_filter, 0);
+ for(unsigned int j = 0; j < d_taps_per_filter; j++) {
+ ourtaps[d_int_rate - 1 - i][j] = tmp_taps[i + j*d_int_rate];
+ }
+
+ // Build a filter for each channel and add it's taps to it
+ ourfilter[i]->set_taps(ourtaps[d_int_rate-1-i]);
+ }
+
+ // Set the history to ensure enough input items for each filter
+ set_history(d_taps_per_filter + 1);
+
+ d_updated = true;
+ }
+
+ void
+ pfb_arb_resampler_fff_impl::create_diff_taps(const std::vector<float> &newtaps,
+ std::vector<float> &difftaps)
+ {
+ // Calculate the differential taps (derivative filter) by taking the difference
+ // between two taps. Duplicate the last one to make both filters the same length.
+ float tap;
+ difftaps.clear();
+ for(unsigned int i = 0; i < newtaps.size()-1; i++) {
+ tap = newtaps[i+1] - newtaps[i];
+ difftaps.push_back(tap);
+ }
+ difftaps.push_back(tap);
+ }
+
+ void
+ pfb_arb_resampler_fff_impl::set_taps(const std::vector<float> &taps)
+ {
+ gruel::scoped_lock guard(d_mutex);
+ }
+
+ std::vector<std::vector<float> >
+ pfb_arb_resampler_fff_impl::taps() const
+ {
+ return d_taps;
+ }
+
+ void
+ pfb_arb_resampler_fff_impl::print_taps()
+ {
+ unsigned int i, j;
+ for(i = 0; i < d_int_rate; i++) {
+ printf("filter[%d]: [", i);
+ for(j = 0; j < d_taps_per_filter; j++) {
+ printf(" %.4e", d_taps[i][j]);
+ }
+ printf("]\n");
+ }
+ }
+
+ void
+ pfb_arb_resampler_fff_impl::set_rate(float rate)
+ {
+ gruel::scoped_lock guard(d_mutex);
+
+ d_dec_rate = (unsigned int)floor(d_int_rate/rate);
+ d_flt_rate = (d_int_rate/rate) - d_dec_rate;
+ set_relative_rate(rate);
+ }
+
+ void
+ pfb_arb_resampler_fff_impl::set_phase(float ph)
+ {
+ gruel::scoped_lock guard(d_mutex);
+ if((ph < 0) || (ph >= 2.0*M_PI)) {
+ throw std::runtime_error("pfb_arb_resampler_ccf: set_phase value out of bounds [0, 2pi).\n");
+ }
+
+ float ph_diff = 2.0*M_PI / (float)d_filters.size();
+ d_last_filter = static_cast<int>(ph / ph_diff);
+ }
+
+ float
+ pfb_arb_resampler_fff_impl::phase() const
+ {
+ float ph_diff = 2.0*M_PI / static_cast<float>(d_filters.size());
+ return d_last_filter * ph_diff;
+ }
+
+ int
+ pfb_arb_resampler_fff_impl::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ gruel::scoped_lock guard(d_mutex);
+
+ float *in = (float*)input_items[0];
+ float *out = (float*)output_items[0];
+
+ if(d_updated) {
+ d_updated = false;
+ return 0; // history requirements may have changed.
+ }
+
+ int i = 0, count = d_start_index;
+ unsigned int j;
+ float o0, o1;
+
+ // Restore the last filter position
+ j = d_last_filter;
+
+ // produce output as long as we can and there are enough input samples
+ int max_input = ninput_items[0] - (int)d_taps_per_filter;
+ while((i < noutput_items) && (count < max_input)) {
+ // start j by wrapping around mod the number of channels
+ while((j < d_int_rate) && (i < noutput_items)) {
+ // Take the current filter and derivative filter output
+ o0 = d_filters[j]->filter(&in[count]);
+ o1 = d_diff_filters[j]->filter(&in[count]);
+
+ out[i] = o0 + o1*d_acc; // linearly interpolate between samples
+ i++;
+
+ // Adjust accumulator and index into filterbank
+ d_acc += d_flt_rate;
+ j += d_dec_rate + (int)floor(d_acc);
+ d_acc = fmodf(d_acc, 1.0);
+ }
+ if(i < noutput_items) { // keep state for next entry
+ float ss = (int)(j / d_int_rate); // number of items to skip ahead by
+ count += ss; // we have fully consumed another input
+ j = j % d_int_rate; // roll filter around
+ }
+ }
+
+ // Store the current filter position and start of next sample
+ d_last_filter = j;
+ d_start_index = std::max(0, count - ninput_items[0]);
+
+ // consume all we've processed but no more than we can
+ consume_each(std::min(count, ninput_items[0]));
+ return i;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/pfb_arb_resampler_fff_impl.h b/gr-filter/lib/pfb_arb_resampler_fff_impl.h
new file mode 100644
index 0000000000..5889627114
--- /dev/null
+++ b/gr-filter/lib/pfb_arb_resampler_fff_impl.h
@@ -0,0 +1,88 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009-2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_PFB_ARB_RESAMPLER_FFF_IMPL_H
+#define INCLUDED_PFB_ARB_RESAMPLER_FFF_IMPL_H
+
+#include <filter/pfb_arb_resampler_fff.h>
+#include <filter/fir_filter.h>
+#include <gruel/thread.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API pfb_arb_resampler_fff_impl : public pfb_arb_resampler_fff
+ {
+ private:
+ std::vector<kernel::fir_filter_fff*> d_filters;
+ std::vector<kernel::fir_filter_fff*> d_diff_filters;
+ std::vector< std::vector<float> > d_taps;
+ std::vector< std::vector<float> > d_dtaps;
+ unsigned int d_int_rate; // the number of filters (interpolation rate)
+ unsigned int d_dec_rate; // the stride through the filters (decimation rate)
+ float d_flt_rate; // residual rate for the linear interpolation
+ float d_acc;
+ unsigned int d_last_filter;
+ int d_start_index;
+ unsigned int d_taps_per_filter;
+ bool d_updated;
+ gruel::mutex d_mutex; // mutex to protect set/work access
+
+ void create_diff_taps(const std::vector<float> &newtaps,
+ std::vector<float> &difftaps);
+
+ /*!
+ * Resets the filterbank's filter taps with the new prototype filter
+ * \param newtaps (vector of floats) The prototype filter to populate the filterbank.
+ * The taps should be generated at the interpolated sampling rate.
+ * \param ourtaps (vector of floats) Reference to our internal member of holding the taps.
+ * \param ourfilter (vector of filters) Reference to our internal filter to set the taps for.
+ */
+ void create_taps(const std::vector<float> &newtaps,
+ std::vector< std::vector<float> > &ourtaps,
+ std::vector<kernel::fir_filter_fff*> &ourfilter);
+ public:
+ pfb_arb_resampler_fff_impl(float rate,
+ const std::vector<float> &taps,
+ unsigned int filter_size);
+
+ ~pfb_arb_resampler_fff_impl();
+
+ void set_taps(const std::vector<float> &taps);
+ std::vector<std::vector<float> > taps() const;
+ void print_taps();
+ void set_rate(float rate);
+
+ void set_phase(float ph);
+ float phase() const;
+
+ int general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_PFB_ARB_RESAMPLER_FFF_IMPL_H */
diff --git a/gr-filter/lib/pfb_channelizer_ccf_impl.cc b/gr-filter/lib/pfb_channelizer_ccf_impl.cc
new file mode 100644
index 0000000000..ca92066f51
--- /dev/null
+++ b/gr-filter/lib/pfb_channelizer_ccf_impl.cc
@@ -0,0 +1,192 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pfb_channelizer_ccf_impl.h"
+#include <gr_io_signature.h>
+
+namespace gr {
+ namespace filter {
+
+ pfb_channelizer_ccf::sptr pfb_channelizer_ccf::make(unsigned int nfilts,
+ const std::vector<float> &taps,
+ float oversample_rate)
+ {
+ return gnuradio::get_initial_sptr(new pfb_channelizer_ccf_impl(nfilts, taps,
+ oversample_rate));
+ }
+
+ pfb_channelizer_ccf_impl::pfb_channelizer_ccf_impl(unsigned int nfilts,
+ const std::vector<float> &taps,
+ float oversample_rate)
+ : gr_block("pfb_channelizer_ccf",
+ gr_make_io_signature(nfilts, nfilts, sizeof(gr_complex)),
+ gr_make_io_signature(1, nfilts, sizeof(gr_complex))),
+ polyphase_filterbank(nfilts, taps),
+ d_updated(false), d_oversample_rate(oversample_rate)
+ {
+ // The over sampling rate must be rationally related to the number of channels
+ // in that it must be N/i for i in [1,N], which gives an outputsample rate
+ // of [fs/N, fs] where fs is the input sample rate.
+ // This tests the specified input sample rate to see if it conforms to this
+ // requirement within a few significant figures.
+ double intp = 0;
+ double fltp = modf(nfilts / oversample_rate, &intp);
+ if(fltp != 0.0)
+ throw std::invalid_argument("pfb_channelizer: oversample rate must be N/i for i in [1, N]");
+
+ set_relative_rate(1.0/intp);
+
+ // Default channel map
+ d_channel_map.resize(d_nfilts);
+ for(unsigned int i = 0; i < d_nfilts; i++) {
+ d_channel_map[i] = i;
+ }
+
+ // Although the filters change, we use this look up table
+ // to set the index of the FFT input buffer, which equivalently
+ // performs the FFT shift operation on every other turn.
+ d_rate_ratio = (int)rintf(d_nfilts / d_oversample_rate);
+ d_idxlut = new int[d_nfilts];
+ for(unsigned int i = 0; i < d_nfilts; i++) {
+ d_idxlut[i] = d_nfilts - ((i + d_rate_ratio) % d_nfilts) - 1;
+ }
+
+ // Calculate the number of filtering rounds to do to evenly
+ // align the input vectors with the output channels
+ d_output_multiple = 1;
+ while((d_output_multiple * d_rate_ratio) % d_nfilts != 0)
+ d_output_multiple++;
+ set_output_multiple(d_output_multiple);
+
+ set_history(d_taps_per_filter+1);
+ }
+
+ pfb_channelizer_ccf_impl::~pfb_channelizer_ccf_impl()
+ {
+ delete [] d_idxlut;
+ }
+
+ void
+ pfb_channelizer_ccf_impl::set_taps(const std::vector<float> &taps)
+ {
+ gruel::scoped_lock guard(d_mutex);
+
+ polyphase_filterbank::set_taps(taps);
+ set_history(d_taps_per_filter+1);
+ d_updated = true;
+ }
+
+ void
+ pfb_channelizer_ccf_impl::print_taps()
+ {
+ polyphase_filterbank::print_taps();
+ }
+
+ std::vector<std::vector<float> >
+ pfb_channelizer_ccf_impl::taps() const
+ {
+ return polyphase_filterbank::taps();
+ }
+
+ void
+ pfb_channelizer_ccf_impl::set_channel_map(const std::vector<int> &map)
+ {
+ gruel::scoped_lock guard(d_mutex);
+
+ if(map.size() > 0) {
+ unsigned int max = (unsigned int)*std::max_element(map.begin(), map.end());
+ unsigned int min = (unsigned int)*std::min_element(map.begin(), map.end());
+ if((max >= d_nfilts) || (min < 0)) {
+ throw std::invalid_argument("pfb_channelizer_ccf_impl::set_channel_map: map range out of bounds.\n");
+ }
+ d_channel_map = map;
+ }
+ }
+
+ std::vector<int>
+ pfb_channelizer_ccf_impl::channel_map() const
+ {
+ return d_channel_map;
+ }
+
+ int
+ pfb_channelizer_ccf_impl::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ gruel::scoped_lock guard(d_mutex);
+
+ gr_complex *in = (gr_complex *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ if(d_updated) {
+ d_updated = false;
+ return 0; // history requirements may have changed.
+ }
+
+ size_t noutputs = output_items.size();
+
+ int n=1, i=-1, j=0, oo=0, last;
+ int toconsume = (int)rintf(noutput_items/d_oversample_rate);
+ while(n <= toconsume) {
+ j = 0;
+ i = (i + d_rate_ratio) % d_nfilts;
+ last = i;
+ while(i >= 0) {
+ in = (gr_complex*)input_items[j];
+ d_fft->get_inbuf()[d_idxlut[j]] = d_filters[i]->filter(&in[n]);
+ j++;
+ i--;
+ }
+
+ i = d_nfilts-1;
+ while(i > last) {
+ in = (gr_complex*)input_items[j];
+ d_fft->get_inbuf()[d_idxlut[j]] = d_filters[i]->filter(&in[n-1]);
+ j++;
+ i--;
+ }
+
+ n += (i+d_rate_ratio) >= (int)d_nfilts;
+
+ // despin through FFT
+ d_fft->execute();
+
+ // Send to output channels
+ for(unsigned int nn = 0; nn < noutputs; nn++) {
+ out = (gr_complex*)output_items[nn];
+ out[oo] = d_fft->get_outbuf()[d_channel_map[nn]];
+ }
+ oo++;
+ }
+
+ consume_each(toconsume);
+ return noutput_items;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/pfb_channelizer_ccf_impl.h b/gr-filter/lib/pfb_channelizer_ccf_impl.h
new file mode 100644
index 0000000000..16b112b9a0
--- /dev/null
+++ b/gr-filter/lib/pfb_channelizer_ccf_impl.h
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_FILTER_PFB_CHANNELIZER_CCF_IMPL_H
+#define INCLUDED_FILTER_PFB_CHANNELIZER_CCF_IMPL_H
+
+#include <filter/pfb_channelizer_ccf.h>
+#include <filter/polyphase_filterbank.h>
+#include <filter/fir_filter.h>
+#include <fft/fft.h>
+#include <gruel/thread.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API pfb_channelizer_ccf_impl : public pfb_channelizer_ccf, kernel::polyphase_filterbank
+ {
+ private:
+ bool d_updated;
+ float d_oversample_rate;
+ int *d_idxlut;
+ int d_rate_ratio;
+ int d_output_multiple;
+ std::vector<int> d_channel_map;
+ gruel::mutex d_mutex; // mutex to protect set/work access
+
+ public:
+ pfb_channelizer_ccf_impl(unsigned int nfilts,
+ const std::vector<float> &taps,
+ float oversample_rate);
+
+ ~pfb_channelizer_ccf_impl();
+
+ void set_taps(const std::vector<float> &taps);
+ void print_taps();
+ std::vector<std::vector<float> > taps() const;
+
+ void set_channel_map(const std::vector<int> &map);
+ std::vector<int> channel_map() const;
+
+ int general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif
diff --git a/gr-filter/lib/pfb_decimator_ccf_impl.cc b/gr-filter/lib/pfb_decimator_ccf_impl.cc
new file mode 100644
index 0000000000..f9a60cb28d
--- /dev/null
+++ b/gr-filter/lib/pfb_decimator_ccf_impl.cc
@@ -0,0 +1,137 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pfb_decimator_ccf_impl.h"
+#include <gr_io_signature.h>
+
+namespace gr {
+ namespace filter {
+
+ pfb_decimator_ccf::sptr
+ pfb_decimator_ccf::make(unsigned int decim,
+ const std::vector<float> &taps,
+ unsigned int channel)
+ {
+ return gnuradio::get_initial_sptr
+ (new pfb_decimator_ccf_impl(decim, taps, channel));
+ }
+
+
+ pfb_decimator_ccf_impl::pfb_decimator_ccf_impl(unsigned int decim,
+ const std::vector<float> &taps,
+ unsigned int channel)
+ : gr_sync_block("pfb_decimator_ccf",
+ gr_make_io_signature(decim, decim, sizeof(gr_complex)),
+ gr_make_io_signature(1, 1, sizeof(gr_complex))),
+ polyphase_filterbank(decim, taps),
+ d_updated(false), d_chan(channel)
+ {
+ d_rate = decim;
+ d_rotator = new gr_complex[d_rate];
+
+ set_relative_rate(1.0/(float)decim);
+ set_history(d_taps_per_filter+1);
+ }
+
+ pfb_decimator_ccf_impl::~pfb_decimator_ccf_impl()
+ {
+ }
+
+ void
+ pfb_decimator_ccf_impl::set_taps(const std::vector<float> &taps)
+ {
+ gruel::scoped_lock guard(d_mutex);
+
+ polyphase_filterbank::set_taps(taps);
+ set_history(d_taps_per_filter+1);
+ d_updated = true;
+ }
+
+ void
+ pfb_decimator_ccf_impl::print_taps()
+ {
+ polyphase_filterbank::print_taps();
+ }
+
+ std::vector<std::vector<float> >
+ pfb_decimator_ccf_impl::taps() const
+ {
+ return polyphase_filterbank::taps();
+ }
+
+#define ROTATEFFT
+
+ int
+ pfb_decimator_ccf_impl::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ gruel::scoped_lock guard(d_mutex);
+
+ gr_complex *in;
+ gr_complex *out = (gr_complex *)output_items[0];
+
+ if(d_updated) {
+ d_updated = false;
+ return 0; // history requirements may have changed.
+ }
+
+ int i;
+ for(i = 0; i < noutput_items; i++) {
+ // Move through filters from bottom to top
+ out[i] = 0;
+ for(int j = d_rate-1; j >= 0; j--) {
+ // Take in the items from the first input stream to d_rate
+ in = (gr_complex*)input_items[d_rate - 1 - j];
+
+ // Filter current input stream from bottom filter to top
+ // The rotate them by expj(j*k*2pi/M) where M is the number of filters
+ // (the decimation rate) and k is the channel number to extract
+
+ // This is the real math that goes on; we abuse the FFT to do this quickly
+ // for decimation rates > N where N is a small number (~5):
+ // out[i] += d_filters[j]->filter(&in[i])*gr_expj(j*d_chan*2*M_PI/d_rate);
+#ifdef ROTATEFFT
+ d_fft->get_inbuf()[j] = d_filters[j]->filter(&in[i]);
+#else
+ out[i] += d_filters[j]->filter(&in[i])*d_rotator[i];
+#endif
+ }
+
+#ifdef ROTATEFFT
+ // Perform the FFT to do the complex multiply despinning for all channels
+ d_fft->execute();
+
+ // Select only the desired channel out
+ out[i] = d_fft->get_outbuf()[d_chan];
+#endif
+ }
+
+ return noutput_items;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/pfb_decimator_ccf_impl.h b/gr-filter/lib/pfb_decimator_ccf_impl.h
new file mode 100644
index 0000000000..c4338a5eca
--- /dev/null
+++ b/gr-filter/lib/pfb_decimator_ccf_impl.h
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_PFB_DECIMATOR_CCF_IMPL_H
+#define INCLUDED_PFB_DECIMATOR_CCF_IMPL_H
+
+#include <filter/pfb_decimator_ccf.h>
+#include <filter/polyphase_filterbank.h>
+#include <filter/fir_filter.h>
+#include <fft/fft.h>
+#include <gruel/thread.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API pfb_decimator_ccf_impl : public pfb_decimator_ccf, kernel::polyphase_filterbank
+ {
+ private:
+ bool d_updated;
+ unsigned int d_rate;
+ unsigned int d_chan;
+ gr_complex *d_rotator;
+ gruel::mutex d_mutex; // mutex to protect set/work access
+
+ public:
+ pfb_decimator_ccf_impl(unsigned int decim,
+ const std::vector<float> &taps,
+ unsigned int channel);
+
+ ~pfb_decimator_ccf_impl();
+
+ void set_taps(const std::vector<float> &taps);
+ void print_taps();
+ std::vector<std::vector<float> > taps() const;
+ //void set_channel(unsigned int channel);
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_PFB_DECIMATOR_CCF_IMPL_H */
diff --git a/gr-filter/lib/pfb_interpolator_ccf_impl.cc b/gr-filter/lib/pfb_interpolator_ccf_impl.cc
new file mode 100644
index 0000000000..572db728b3
--- /dev/null
+++ b/gr-filter/lib/pfb_interpolator_ccf_impl.cc
@@ -0,0 +1,107 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pfb_interpolator_ccf_impl.h"
+#include <gr_io_signature.h>
+
+namespace gr {
+ namespace filter {
+
+ pfb_interpolator_ccf::sptr
+ pfb_interpolator_ccf::make(unsigned int interp,
+ const std::vector<float> &taps)
+ {
+ return gnuradio::get_initial_sptr
+ (new pfb_interpolator_ccf_impl(interp, taps));
+ }
+
+
+ pfb_interpolator_ccf_impl::pfb_interpolator_ccf_impl(unsigned int interp,
+ const std::vector<float> &taps)
+ : gr_sync_interpolator("pfb_interpolator_ccf",
+ gr_make_io_signature(1, 1, sizeof(gr_complex)),
+ gr_make_io_signature(1, 1, sizeof(gr_complex)),
+ interp),
+ polyphase_filterbank(interp, taps),
+ d_updated (false), d_rate(interp)
+ {
+ set_history(d_taps_per_filter+1);
+ }
+
+ pfb_interpolator_ccf_impl::~pfb_interpolator_ccf_impl()
+ {
+ }
+
+ void
+ pfb_interpolator_ccf_impl::set_taps(const std::vector<float> &taps)
+ {
+ gruel::scoped_lock guard(d_mutex);
+
+ polyphase_filterbank::set_taps(taps);
+ set_history(d_taps_per_filter+1);
+ d_updated = true;
+ }
+
+ void
+ pfb_interpolator_ccf_impl::print_taps()
+ {
+ polyphase_filterbank::print_taps();
+ }
+
+ std::vector<std::vector<float> >
+ pfb_interpolator_ccf_impl::taps() const
+ {
+ return polyphase_filterbank::taps();
+ }
+
+ int
+ pfb_interpolator_ccf_impl::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ gr_complex *in = (gr_complex*)input_items[0];
+ gr_complex *out = (gr_complex*)output_items[0];
+
+ if(d_updated) {
+ d_updated = false;
+ return 0; // history requirements may have changed.
+ }
+
+ int i = 0, count = 0;
+
+ while(i < noutput_items) {
+ for(unsigned int j = 0; j < d_rate; j++) {
+ out[i] = d_filters[j]->filter(&in[count]);
+ i++;
+ }
+ count++;
+ }
+
+ return i;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/pfb_interpolator_ccf_impl.h b/gr-filter/lib/pfb_interpolator_ccf_impl.h
new file mode 100644
index 0000000000..7e1fe2ca11
--- /dev/null
+++ b/gr-filter/lib/pfb_interpolator_ccf_impl.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_PFB_INTERPOLATOR_CCF_IMPL_H
+#define INCLUDED_PFB_INTERPOLATOR_CCF_IMPL_H
+
+#include <filter/pfb_interpolator_ccf.h>
+#include <filter/polyphase_filterbank.h>
+#include <filter/fir_filter.h>
+#include <fft/fft.h>
+#include <gruel/thread.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API pfb_interpolator_ccf_impl : public pfb_interpolator_ccf, kernel::polyphase_filterbank
+ {
+ private:
+ bool d_updated;
+ unsigned int d_rate;
+ gruel::mutex d_mutex; // mutex to protect set/work access
+
+ public:
+ pfb_interpolator_ccf_impl(unsigned int interp,
+ const std::vector<float> &taps);
+
+ ~pfb_interpolator_ccf_impl();
+
+ void set_taps(const std::vector<float> &taps);
+ void print_taps();
+ std::vector<std::vector<float> > taps() const;
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_PFB_INTERPOLATOR_CCF_IMPL_H */
diff --git a/gr-filter/lib/pfb_synthesizer_ccf_impl.cc b/gr-filter/lib/pfb_synthesizer_ccf_impl.cc
new file mode 100644
index 0000000000..1e9c099c1e
--- /dev/null
+++ b/gr-filter/lib/pfb_synthesizer_ccf_impl.cc
@@ -0,0 +1,288 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pfb_synthesizer_ccf_impl.h"
+#include <gr_io_signature.h>
+#include <cstdio>
+
+namespace gr {
+ namespace filter {
+
+ pfb_synthesizer_ccf::sptr
+ pfb_synthesizer_ccf::make(unsigned int numchans,
+ const std::vector<float> &taps,
+ bool twox)
+ {
+ return gnuradio::get_initial_sptr
+ (new pfb_synthesizer_ccf_impl(numchans, taps, twox));
+ }
+
+
+ pfb_synthesizer_ccf_impl::pfb_synthesizer_ccf_impl(unsigned int numchans,
+ const std::vector<float> &taps,
+ bool twox)
+ : gr_sync_interpolator("pfb_synthesizer_ccf",
+ gr_make_io_signature(1, numchans, sizeof(gr_complex)),
+ gr_make_io_signature(1, 1, sizeof(gr_complex)),
+ numchans),
+ d_updated (false), d_numchans(numchans), d_state(0)
+ {
+ // set up 2x multiplier; if twox==True, set to 2, otherwise to 1
+ d_twox = (twox ? 2 : 1);
+ if(d_numchans % d_twox != 0) {
+ throw std::invalid_argument("pfb_synthesizer_ccf: number of channels must be even for 2x oversampling.\n");
+ }
+
+ d_filters = std::vector<kernel::fir_filter_with_buffer_ccf*>(d_twox*d_numchans);
+ d_channel_map.resize(d_twox*d_numchans);
+
+ // Create a FIR filter for each channel and zero out the taps
+ std::vector<float> vtaps(0, d_twox*d_numchans);
+ for(unsigned int i = 0; i < d_twox*d_numchans; i++) {
+ d_filters[i] = new kernel::fir_filter_with_buffer_ccf(vtaps);
+ d_channel_map[i] = i;
+ }
+
+ // Now, actually set the filters' taps
+ set_taps(taps);
+
+ // Create the IFFT to handle the input channel rotations
+ d_fft = new fft::fft_complex(d_twox*d_numchans, false);
+ memset(d_fft->get_inbuf(), 0, d_twox*d_numchans*sizeof(gr_complex));
+
+ set_output_multiple(d_numchans);
+ }
+
+ pfb_synthesizer_ccf_impl::~pfb_synthesizer_ccf_impl()
+ {
+ for(unsigned int i = 0; i < d_twox*d_numchans; i++) {
+ delete d_filters[i];
+ }
+ }
+
+ void
+ pfb_synthesizer_ccf_impl::set_taps(const std::vector<float> &taps)
+ {
+ gruel::scoped_lock guard(d_mutex);
+
+ if(d_twox == 1)
+ set_taps1(taps);
+ else
+ set_taps2(taps);
+
+ // Set the history to ensure enough input items for each filter
+ set_history(d_taps_per_filter+1);
+
+ d_updated = true;
+ }
+
+ void
+ pfb_synthesizer_ccf_impl::set_taps1(const std::vector<float> &taps)
+ {
+ unsigned int i,j;
+
+ unsigned int ntaps = taps.size();
+ d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_numchans);
+
+ // Create d_numchan vectors to store each channel's taps
+ d_taps.resize(d_numchans);
+
+ // Make a vector of the taps plus fill it out with 0's to fill
+ // each polyphase filter with exactly d_taps_per_filter
+ std::vector<float> tmp_taps;
+ tmp_taps = taps;
+ while((float)(tmp_taps.size()) < d_numchans*d_taps_per_filter) {
+ tmp_taps.push_back(0.0);
+ }
+
+ // Partition the filter
+ for(i = 0; i < d_numchans; i++) {
+ // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out
+ d_taps[i] = std::vector<float>(d_taps_per_filter, 0);
+ for(j = 0; j < d_taps_per_filter; j++) {
+ d_taps[i][j] = tmp_taps[i + j*d_numchans]; // add taps to channels in reverse order
+ }
+
+ // Build a filter for each channel and add it's taps to it
+ d_filters[i]->set_taps(d_taps[i]);
+ }
+ }
+
+ void
+ pfb_synthesizer_ccf_impl::set_taps2 (const std::vector<float> &taps)
+ {
+ unsigned int i,j;
+ int state = 0;
+
+ unsigned int ntaps = taps.size();
+ d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_numchans);
+
+ // Create d_numchan vectors to store each channel's taps
+ d_taps.resize(d_twox*d_numchans);
+
+ // Make a vector of the taps plus fill it out with 0's to fill
+ // each polyphase filter with exactly d_taps_per_filter
+ std::vector<float> tmp_taps;
+ tmp_taps = taps;
+ while((float)(tmp_taps.size()) < d_numchans*d_taps_per_filter) {
+ tmp_taps.push_back(0.0);
+ }
+
+ // Partition the filter
+ for(i = 0; i < d_numchans; i++) {
+ // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out
+ d_taps[i] = std::vector<float>(d_taps_per_filter, 0);
+ d_taps[d_numchans+i] = std::vector<float>(d_taps_per_filter, 0);
+ state = 0;
+ for(j = 0; j < d_taps_per_filter; j++) {
+ // add taps to channels in reverse order
+ // Zero out every other tap
+ if(state == 0) {
+ d_taps[i][j] = tmp_taps[i + j*d_numchans];
+ d_taps[d_numchans + i][j] = 0;
+ state = 1;
+ }
+ else {
+ d_taps[i][j] = 0;
+ d_taps[d_numchans + i][j] = tmp_taps[i + j*d_numchans];
+ state = 0;
+ }
+ }
+
+ // Build a filter for each channel and add it's taps to it
+ d_filters[i]->set_taps(d_taps[i]);
+ d_filters[d_numchans + i]->set_taps(d_taps[d_numchans + i]);
+ }
+ }
+
+ void
+ pfb_synthesizer_ccf_impl::print_taps()
+ {
+ unsigned int i, j;
+ for(i = 0; i < d_twox*d_numchans; i++) {
+ printf("filter[%d]: [", i);
+ for(j = 0; j < d_taps_per_filter; j++) {
+ printf(" %.4e", d_taps[i][j]);
+ }
+ printf("]\n\n");
+ }
+ }
+
+ std::vector< std::vector<float> >
+ pfb_synthesizer_ccf_impl::taps() const
+ {
+ return d_taps;
+ }
+
+ void
+ pfb_synthesizer_ccf_impl::set_channel_map(const std::vector<int> &map)
+ {
+ gruel::scoped_lock guard(d_mutex);
+
+ if(map.size() > 0) {
+ unsigned int max = (unsigned int)*std::max_element(map.begin(), map.end());
+ unsigned int min = (unsigned int)*std::min_element(map.begin(), map.end());
+ if((max >= d_twox*d_numchans) || (min < 0)) {
+ throw std::invalid_argument("gr_pfb_synthesizer_ccf::set_channel_map: map range out of bounds.\n");
+ }
+ d_channel_map = map;
+
+ // Zero out fft buffer so that unused channels are always 0
+ memset(d_fft->get_inbuf(), 0,d_twox*d_numchans*sizeof(gr_complex));
+ }
+ }
+
+ std::vector<int>
+ pfb_synthesizer_ccf_impl::channel_map() const
+ {
+ return d_channel_map;
+ }
+
+ int
+ pfb_synthesizer_ccf_impl::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ gruel::scoped_lock guard(d_mutex);
+
+ gr_complex *in = (gr_complex*)input_items[0];
+ gr_complex *out = (gr_complex*)output_items[0];
+
+ if(d_updated) {
+ d_updated = false;
+ return 0; // history requirements may have changed.
+ }
+
+ unsigned int n, i;
+ size_t ninputs = input_items.size();
+
+ // Algoritm for critically sampled channels
+ if(d_twox == 1) {
+ for(n = 0; n < noutput_items/d_numchans; n++) {
+ for(i = 0; i < ninputs; i++) {
+ in = (gr_complex*)input_items[i];
+ d_fft->get_inbuf()[d_channel_map[i]] = in[n];
+ }
+
+ // spin through IFFT
+ d_fft->execute();
+
+ for(i = 0; i < d_numchans; i++) {
+ out[i] = d_filters[i]->filter(d_fft->get_outbuf()[i]);
+ }
+ out += d_numchans;
+ }
+ }
+
+ // Algorithm for oversampling by 2x
+ else {
+ for(n = 0; n < noutput_items/d_numchans; n++) {
+ for(i = 0; i < ninputs; i++) {
+ in = (gr_complex*)input_items[i];
+ d_fft->get_inbuf()[d_channel_map[i]] = in[n];
+ }
+
+ // spin through IFFT
+ d_fft->execute();
+
+ // Output is sum of two filters, but the input buffer to the filters must be circularly
+ // shifted by numchans every time through, done by using d_state to determine which IFFT
+ // buffer position to pull from.
+ for(i = 0; i < d_numchans; i++) {
+ out[i] = d_filters[i]->filter(d_fft->get_outbuf()[d_state*d_numchans+i]);
+ out[i] += d_filters[d_numchans+i]->filter(d_fft->get_outbuf()[(d_state^1)*d_numchans+i]);
+ }
+ d_state ^= 1;
+
+ out += d_numchans;
+ }
+ }
+
+ return noutput_items;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/pfb_synthesizer_ccf_impl.h b/gr-filter/lib/pfb_synthesizer_ccf_impl.h
new file mode 100644
index 0000000000..adffc143f2
--- /dev/null
+++ b/gr-filter/lib/pfb_synthesizer_ccf_impl.h
@@ -0,0 +1,85 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_PFB_SYNTHESIZER_CCF_IMPL_H
+#define INCLUDED_PFB_SYNTHESIZER_CCF_IMPL_H
+
+#include <filter/pfb_synthesizer_ccf.h>
+#include <filter/fir_filter_with_buffer.h>
+#include <fft/fft.h>
+#include <gruel/thread.h>
+
+namespace gr {
+ namespace filter {
+
+ // While this is a polyphase_filterbank, we don't use the normal
+ // parent class because we have to use the fir_filter_with_buffer
+ // objects instead of normal filters.
+
+ class FILTER_API pfb_synthesizer_ccf_impl : public pfb_synthesizer_ccf
+ {
+ private:
+ bool d_updated;
+ unsigned int d_numchans;
+ unsigned int d_taps_per_filter;
+ fft::fft_complex *d_fft;
+ std::vector< kernel::fir_filter_with_buffer_ccf*> d_filters;
+ std::vector< std::vector<float> > d_taps;
+ int d_state;
+ std::vector<int> d_channel_map;
+ unsigned int d_twox;
+ gruel::mutex d_mutex; // mutex to protect set/work access
+
+ /*!
+ * \brief Tap setting algorithm for critically sampled channels
+ */
+ void set_taps1(const std::vector<float> &taps);
+
+ /*!
+ * \brief Tap setting algorithm for 2x over-sampled channels
+ */
+ void set_taps2(const std::vector<float> &taps);
+
+
+ public:
+ pfb_synthesizer_ccf_impl(unsigned int numchans,
+ const std::vector<float> &taps,
+ bool twox);
+ ~pfb_synthesizer_ccf_impl();
+
+ void set_taps(const std::vector<float> &taps);
+ std::vector<std::vector<float> > taps() const;
+ void print_taps();
+
+ void set_channel_map(const std::vector<int> &map);
+ std::vector<int> channel_map() const;
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_PFB_SYNTHESIZER_CCF_IMPL_H */
diff --git a/gr-filter/lib/pm_remez.cc b/gr-filter/lib/pm_remez.cc
new file mode 100644
index 0000000000..e7136bd83a
--- /dev/null
+++ b/gr-filter/lib/pm_remez.cc
@@ -0,0 +1,834 @@
+/**************************************************************************
+ * Parks-McClellan algorithm for FIR filter design (C version)
+ *-------------------------------------------------
+ * Copyright (c) 1995,1998 Jake Janovetz (janovetz@uiuc.edu)
+ * Copyright (c) 2004 Free Software Foundation, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA
+ *
+ *
+ * Sep 1999 - Paul Kienzle (pkienzle@cs.indiana.edu)
+ * Modified for use in octave as a replacement for the matlab function
+ * remez.mex. In particular, magnitude responses are required for all
+ * band edges rather than one per band, griddensity is a parameter,
+ * and errors are returned rather than printed directly.
+ * Mar 2000 - Kai Habel (kahacjde@linux.zrz.tu-berlin.de)
+ * Change: ColumnVector x=arg(i).vector_value();
+ * to: ColumnVector x(arg(i).vector_value());
+ * There appear to be some problems with the routine search. See comments
+ * therein [search for PAK:]. I haven't looked closely at the rest
+ * of the code---it may also have some problems.
+ *************************************************************************/
+
+/*
+ * This code was extracted from octave.sf.net, and wrapped with
+ * GNU Radio glue.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <filter/pm_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
+
+namespace gr {
+ namespace filter {
+
+#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
+
+ /*******************
+ * create_dense_grid
+ *=================
+ *
+ * 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
+ create_dense_grid(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;
+ }
+ }
+
+
+ /********************
+ * initial_guess
+ *==============
+ * 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
+ initial_guess(int r, int Ext[], int gridsize)
+ {
+ int i;
+
+ for(i=0; i<=r; i++)
+ Ext[i] = i * (gridsize-1) / r;
+ }
+
+
+ /***********************
+ * calc_parms
+ *===========
+ *
+ *
+ * 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
+ calc_parms(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;
+ }
+ }
+
+
+ /*********************
+ * compute_A
+ *==========
+ * Using values calculated in calc_parms, compute_A 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
+ compute_A(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;
+ }
+
+
+ /************************
+ * calc_error
+ *===========
+ * 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
+ calc_error(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 = compute_A(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;
+ }
+
+
+ /*********************
+ * freq_sample
+ *============
+ * Simple frequency sampling algorithm to determine the impulse
+ * response h[] from A's found in compute_A
+ *
+ *
+ * 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
+ freq_sample(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;
+ }
+ }
+ }
+ }
+
+ /*******************
+ * is_done
+ *========
+ * 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
+ is_done(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
+ */
+ create_dense_grid(r, numtaps, numband, bands, des, weight,
+ gridsize, Grid, D, W, symmetry, griddensity);
+ initial_guess(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++) {
+ calc_parms(r, Ext, Grid, D, W, ad, x, y);
+ calc_error(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(is_done(r, Ext, E))
+ break;
+ }
+
+ calc_parms(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] = compute_A((double)i/numtaps, r, ad, x, y)*c;
+ }
+
+ /*
+ * Frequency sampling design with calculated taps
+ */
+ freq_sample(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>
+ pm_remez(int order,
+ const std::vector<double> &arg_bands,
+ const std::vector<double> &arg_response,
+ const std::vector<double> &arg_weight,
+ const std::string filter_type,
+ int grid_density
+ ) throw (std::runtime_error)
+ {
+ int numtaps = order + 1;
+ if(numtaps < 4)
+ punt("gr_remez: number of taps must be >= 3");
+
+ int numbands = arg_bands.size() / 2;
+ LOCAL_BUFFER(double, bands, numbands * 2);
+ if(numbands < 1 || arg_bands.size() % 2 == 1)
+ punt("gr_remez: must have an even number of band edges");
+
+ for(unsigned int i = 1; i < arg_bands.size(); i++){
+ if(arg_bands[i] < arg_bands[i-1])
+ punt("gr_remez: band edges must be nondecreasing");
+ }
+
+ if(arg_bands[0] < 0 || arg_bands[arg_bands.size() - 1] > 1)
+ punt("gr_remez: band edges must be in the range [0,1]");
+
+ // Divide by 2 to fit with the implementation that uses a
+ // sample rate of [0, 0.5] instead of [0, 1.0]
+ for(int i = 0; i < 2 * numbands; i++)
+ bands[i] = arg_bands[i] / 2;
+
+ LOCAL_BUFFER(double, response, numbands * 2);
+ if(arg_response.size() != arg_bands.size())
+ punt("gr_remez: must have one response magnitude for each band edge");
+
+ for(int i = 0; i < 2 * numbands; i++)
+ response[i] = arg_response[i];
+
+ LOCAL_BUFFER(double, weight, numbands);
+ for(int i = 0; i < numbands; i++)
+ weight[i] = 1.0;
+
+ if(arg_weight.size() != 0) {
+ if((int) arg_weight.size() != numbands)
+ punt("gr_remez: need one weight for each band [=length(band)/2]");
+ for(int i = 0; i < numbands; i++)
+ weight[i] = arg_weight [i];
+ }
+
+ int itype = 0;
+ if(filter_type == "bandpass")
+ itype = BANDPASS;
+ else if(filter_type == "differentiator")
+ itype = DIFFERENTIATOR;
+ else if(filter_type == "hilbert")
+ itype = HILBERT;
+ else
+ punt("gr_remez: unknown ftype '" + filter_type + "'");
+
+ if(grid_density < 16)
+ punt("gr_remez: grid_density is too low; must be >= 16");
+
+ LOCAL_BUFFER(double, coeff, numtaps + 5); // FIXME why + 5?
+ int err = remez(coeff, numtaps, numbands,
+ bands, response, weight, itype, grid_density);
+
+ if(err == -1)
+ punt("gr_remez: failed to converge");
+
+ if(err == -2)
+ punt("gr_remez: insufficient extremals -- cannot continue");
+
+ if(err == -3)
+ punt("gr_remez: too many extremals -- cannot continue");
+
+ return std::vector<double>(&coeff[0], &coeff[numtaps]);
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/polyphase_filterbank.cc b/gr-filter/lib/polyphase_filterbank.cc
new file mode 100644
index 0000000000..046c23fc07
--- /dev/null
+++ b/gr-filter/lib/polyphase_filterbank.cc
@@ -0,0 +1,114 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <filter/polyphase_filterbank.h>
+#include <cstdio>
+
+namespace gr {
+ namespace filter {
+ namespace kernel {
+
+ polyphase_filterbank::polyphase_filterbank(unsigned int nfilts,
+ const std::vector<float> &taps)
+ : d_nfilts(nfilts)
+ {
+ d_filters = std::vector<kernel::fir_filter_ccf*>(d_nfilts);
+
+ // Create an FIR filter for each channel and zero out the taps
+ std::vector<float> vtaps(0, d_nfilts);
+ for(unsigned int i = 0; i < d_nfilts; i++) {
+ d_filters[i] = new kernel::fir_filter_ccf(1, vtaps);
+ }
+
+ // Now, actually set the filters' taps
+ set_taps(taps);
+
+ // Create the FFT to handle the output de-spinning of the channels
+ d_fft = new fft::fft_complex(d_nfilts, false);
+ }
+
+ polyphase_filterbank::~polyphase_filterbank()
+ {
+ delete d_fft;
+ for(unsigned int i = 0; i < d_nfilts; i++) {
+ delete d_filters[i];
+ }
+ }
+
+ void
+ polyphase_filterbank::set_taps(const std::vector<float> &taps)
+ {
+ unsigned int i,j;
+
+ unsigned int ntaps = taps.size();
+ d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_nfilts);
+
+ // Create d_numchan vectors to store each channel's taps
+ d_taps.resize(d_nfilts);
+
+ // Make a vector of the taps plus fill it out with 0's to fill
+ // each polyphase filter with exactly d_taps_per_filter
+ std::vector<float> tmp_taps;
+ tmp_taps = taps;
+ while((float)(tmp_taps.size()) < d_nfilts*d_taps_per_filter) {
+ tmp_taps.push_back(0.0);
+ }
+
+ // Partition the filter
+ for(i = 0; i < d_nfilts; i++) {
+ // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out
+ d_taps[i] = std::vector<float>(d_taps_per_filter, 0);
+ for(j = 0; j < d_taps_per_filter; j++) {
+ d_taps[i][j] = tmp_taps[i + j*d_nfilts]; // add taps to channels in reverse order
+ }
+
+ // Build a filter for each channel and add it's taps to it
+ d_filters[i]->set_taps(d_taps[i]);
+ }
+ }
+
+ void
+ polyphase_filterbank::print_taps()
+ {
+ unsigned int i, j;
+ for(i = 0; i < d_nfilts; i++) {
+ printf("filter[%d]: [", i);
+ for(j = 0; j < d_taps_per_filter; j++) {
+ printf(" %.4e", d_taps[i][j]);
+ }
+ printf("]\n\n");
+ }
+ }
+
+ std::vector< std::vector<float> >
+ polyphase_filterbank::taps() const
+ {
+ return d_taps;
+ }
+
+ } /* namespace kernel */
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/qa_filter.cc b/gr-filter/lib/qa_filter.cc
new file mode 100644
index 0000000000..b7760b19ea
--- /dev/null
+++ b/gr-filter/lib/qa_filter.cc
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * This class gathers together all the test cases for the gr-filter
+ * directory into a single test suite. As you create new test cases,
+ * add them here.
+ */
+
+#include <qa_filter.h>
+#include <qa_firdes.h>
+#include <qa_fir_filter_with_buffer.h>
+#include <qa_mmse_fir_interpolator_cc.h>
+#include <qa_mmse_fir_interpolator_ff.h>
+
+CppUnit::TestSuite *
+qa_gr_filter::suite ()
+{
+ CppUnit::TestSuite *s = new CppUnit::TestSuite ("gr-filter");
+
+ s->addTest(gr::filter::qa_firdes::suite());
+ s->addTest(gr::filter::fff::qa_fir_filter_with_buffer_fff::suite());
+ s->addTest(gr::filter::ccc::qa_fir_filter_with_buffer_ccc::suite());
+ s->addTest(gr::filter::ccf::qa_fir_filter_with_buffer_ccf::suite());
+ s->addTest(gr::filter::qa_mmse_fir_interpolator_cc::suite());
+ s->addTest(gr::filter::qa_mmse_fir_interpolator_ff::suite());
+
+ return s;
+}
diff --git a/gr-filter/lib/qa_filter.h b/gr-filter/lib/qa_filter.h
new file mode 100644
index 0000000000..427e7f9f6a
--- /dev/null
+++ b/gr-filter/lib/qa_filter.h
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _QA_GR_FILTER_H_
+#define _QA_GR_FILTER_H_
+
+#include <gruel/attributes.h>
+#include <cppunit/TestSuite.h>
+
+//! collect all the tests for the gr-filter directory
+
+class __GR_ATTR_EXPORT qa_gr_filter {
+ public:
+ //! return suite of tests for all of gr-filter directory
+ static CppUnit::TestSuite *suite ();
+};
+
+
+#endif /* _QA_GR_FILTER_H_ */
diff --git a/gr-filter/lib/qa_fir_filter_with_buffer.cc b/gr-filter/lib/qa_fir_filter_with_buffer.cc
new file mode 100644
index 0000000000..6a1744b0ac
--- /dev/null
+++ b/gr-filter/lib/qa_fir_filter_with_buffer.cc
@@ -0,0 +1,406 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_types.h>
+#include <qa_fir_filter_with_buffer.h>
+#include <filter/fir_filter_with_buffer.h>
+#include <fft/fft.h>
+#include <cppunit/TestAssert.h>
+#include <cmath>
+#include <random.h>
+#include <cstring>
+
+namespace gr {
+ namespace filter {
+
+#define MAX_DATA (16383)
+#define ERR_DELTA (1e-5)
+
+ 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() * MAX_DATA);
+ float im = rint(uniform() * MAX_DATA);
+ buf[i] = gr_complex(re, im);
+ }
+ }
+
+ namespace fff {
+
+ typedef float i_type;
+ typedef float o_type;
+ typedef float tap_type;
+ typedef float acc_type;
+
+ using std::vector;
+
+ static o_type
+ ref_dotprod(const i_type input[], const tap_type taps[], int ntaps)
+ {
+ acc_type sum = 0;
+ for (int i = 0; i < ntaps; i++) {
+ sum += input[i] * taps[i];
+ }
+ return sum;
+ }
+
+ void
+ qa_fir_filter_with_buffer_fff::t1()
+ {
+ test_decimate(1);
+ }
+
+ void
+ qa_fir_filter_with_buffer_fff::t2()
+ {
+ test_decimate(2);
+ }
+
+ void
+ qa_fir_filter_with_buffer_fff::t3()
+ {
+ test_decimate(5);
+ }
+
+ //
+ // Test for ntaps in [0,9], and input lengths in [0,17].
+ // This ensures that we are building the shifted taps correctly,
+ // and exercises all corner cases on input alignment and length.
+ //
+ void
+ qa_fir_filter_with_buffer_fff::test_decimate(unsigned int decimate)
+ {
+ const int MAX_TAPS = 29;
+ const int OUTPUT_LEN = 37;
+ const int INPUT_LEN = MAX_TAPS + OUTPUT_LEN;
+
+ // Mem aligned buffer not really necessary, but why not?
+ i_type *input = fft::malloc_float(INPUT_LEN);
+ i_type *dline = fft::malloc_float(INPUT_LEN);
+ o_type *expected_output = fft::malloc_float(OUTPUT_LEN);
+ o_type *actual_output = fft::malloc_float(OUTPUT_LEN);
+ tap_type *taps = fft::malloc_float(MAX_TAPS);
+
+ srandom(0); // we want reproducibility
+ memset(dline, 0, INPUT_LEN*sizeof(i_type));
+
+ for(int n = 0; n <= MAX_TAPS; n++) {
+ for(int ol = 0; ol <= OUTPUT_LEN; ol++) {
+
+ // build random test case
+ random_floats(input, INPUT_LEN);
+ random_floats(taps, MAX_TAPS);
+
+ // compute expected output values
+ memset(dline, 0, INPUT_LEN*sizeof(i_type));
+ for(int o = 0; o < (int)(ol/decimate); o++) {
+ // use an actual delay line for this test
+ for(int dd = 0; dd < (int)decimate; dd++) {
+ for(int oo = INPUT_LEN-1; oo > 0; oo--)
+ dline[oo] = dline[oo-1];
+ dline[0] = input[decimate*o+dd];
+ }
+ expected_output[o] = ref_dotprod(dline, taps, n);
+ }
+
+ // build filter
+ vector<tap_type> f1_taps(&taps[0], &taps[n]);
+ kernel::fir_filter_with_buffer_fff *f1 = \
+ new kernel::fir_filter_with_buffer_fff(f1_taps);
+
+ // zero the output, then do the filtering
+ memset(actual_output, 0, OUTPUT_LEN*sizeof(o_type));
+ f1->filterNdec(actual_output, input, ol/decimate, decimate);
+
+ // check results
+ //
+ // we use a sloppy error margin because on the x86 architecture,
+ // our reference implementation is using 80 bit floating point
+ // arithmetic, while the SSE version is using 32 bit float point
+ // arithmetic.
+
+ for(int o = 0; o < (int)(ol/decimate); o++) {
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(expected_output[o], actual_output[o],
+ sqrt((float)n)*0.25*MAX_DATA*MAX_DATA * ERR_DELTA);
+ }
+ delete f1;
+ }
+ }
+ fft::free(input);
+ fft::free(dline);
+ fft::free(expected_output);
+ fft::free(actual_output);
+ fft::free(taps);
+ }
+
+ } /* namespace fff */
+
+
+ /**************************************************************/
+
+
+ namespace ccc {
+
+ typedef gr_complex i_type;
+ typedef gr_complex o_type;
+ typedef gr_complex tap_type;
+ typedef gr_complex acc_type;
+
+ using std::vector;
+
+ static o_type
+ ref_dotprod(const i_type input[], const tap_type taps[], int ntaps)
+ {
+ acc_type sum = 0;
+ for(int i = 0; i < ntaps; i++) {
+ sum += input[i] * taps[i];
+ }
+
+ return sum;
+ }
+
+ void
+ qa_fir_filter_with_buffer_ccc::t1()
+ {
+ test_decimate(1);
+ }
+
+ void
+ qa_fir_filter_with_buffer_ccc::t2()
+ {
+ test_decimate(2);
+ }
+
+ void
+ qa_fir_filter_with_buffer_ccc::t3()
+ {
+ test_decimate(5);
+ }
+
+ //
+ // Test for ntaps in [0,9], and input lengths in [0,17].
+ // This ensures that we are building the shifted taps correctly,
+ // and exercises all corner cases on input alignment and length.
+ //
+ void
+ qa_fir_filter_with_buffer_ccc::test_decimate(unsigned int decimate)
+ {
+ const int MAX_TAPS = 29;
+ const int OUTPUT_LEN = 37;
+ const int INPUT_LEN = MAX_TAPS + OUTPUT_LEN;
+
+ // Mem aligned buffer not really necessary, but why not?
+ i_type *input = fft::malloc_complex(INPUT_LEN);
+ i_type *dline = fft::malloc_complex(INPUT_LEN);
+ o_type *expected_output = fft::malloc_complex(OUTPUT_LEN);
+ o_type *actual_output = fft::malloc_complex(OUTPUT_LEN);
+ tap_type *taps = fft::malloc_complex(MAX_TAPS);
+
+ srandom(0); // we want reproducibility
+ memset(dline, 0, INPUT_LEN*sizeof(i_type));
+
+ for(int n = 0; n <= MAX_TAPS; n++) {
+ for(int ol = 0; ol <= OUTPUT_LEN; ol++) {
+
+ // build random test case
+ random_complex(input, INPUT_LEN);
+ random_complex(taps, MAX_TAPS);
+
+ // compute expected output values
+ memset(dline, 0, INPUT_LEN*sizeof(i_type));
+ for(int o = 0; o < (int)(ol/decimate); o++) {
+ // use an actual delay line for this test
+ for(int dd = 0; dd < (int)decimate; dd++) {
+ for(int oo = INPUT_LEN-1; oo > 0; oo--)
+ dline[oo] = dline[oo-1];
+ dline[0] = input[decimate*o+dd];
+ }
+ expected_output[o] = ref_dotprod(dline, taps, n);
+ }
+
+ // build filter
+ vector<tap_type> f1_taps(&taps[0], &taps[n]);
+ kernel::fir_filter_with_buffer_ccc *f1 = \
+ new kernel::fir_filter_with_buffer_ccc(f1_taps);
+
+ // zero the output, then do the filtering
+ memset(actual_output, 0, OUTPUT_LEN*sizeof(o_type));
+ f1->filterNdec(actual_output, input, ol/decimate, decimate);
+
+ // check results
+ //
+ // we use a sloppy error margin because on the x86 architecture,
+ // our reference implementation is using 80 bit floating point
+ // arithmetic, while the SSE version is using 32 bit float point
+ // arithmetic.
+
+ for(int o = 0; o < (int)(ol/decimate); o++) {
+ CPPUNIT_ASSERT_COMPLEXES_EQUAL(expected_output[o], actual_output[o],
+ sqrt((float)n)*0.25*MAX_DATA*MAX_DATA * ERR_DELTA);
+ }
+ delete f1;
+ }
+ }
+ fft::free(input);
+ fft::free(dline);
+ fft::free(expected_output);
+ fft::free(actual_output);
+ fft::free(taps);
+ }
+
+ } /* namespace ccc */
+
+
+ /**************************************************************/
+
+ namespace ccf {
+
+ typedef gr_complex i_type;
+ typedef gr_complex o_type;
+ typedef float tap_type;
+ typedef gr_complex acc_type;
+
+ using std::vector;
+
+ static o_type
+ ref_dotprod(const i_type input[], const tap_type taps[], int ntaps)
+ {
+ acc_type sum = 0;
+ for(int i = 0; i < ntaps; i++) {
+ sum += input[i] * taps[i];
+ }
+
+ //return gr_complex(121,9)*sum;
+ return sum;
+ }
+
+ void
+ qa_fir_filter_with_buffer_ccf::t1()
+ {
+ test_decimate(1);
+ }
+
+ void
+ qa_fir_filter_with_buffer_ccf::t2()
+ {
+ test_decimate(2);
+ }
+
+ void
+ qa_fir_filter_with_buffer_ccf::t3()
+ {
+ test_decimate(5);
+ }
+
+ //
+ // Test for ntaps in [0,9], and input lengths in [0,17].
+ // This ensures that we are building the shifted taps correctly,
+ // and exercises all corner cases on input alignment and length.
+ //
+ void
+ qa_fir_filter_with_buffer_ccf::test_decimate(unsigned int decimate)
+ {
+ const int MAX_TAPS = 29;
+ const int OUTPUT_LEN = 37;
+ const int INPUT_LEN = MAX_TAPS + OUTPUT_LEN;
+
+ // Mem aligned buffer not really necessary, but why not?
+ i_type *input = fft::malloc_complex(INPUT_LEN);
+ i_type *dline = fft::malloc_complex(INPUT_LEN);
+ o_type *expected_output = fft::malloc_complex(OUTPUT_LEN);
+ o_type *actual_output = fft::malloc_complex(OUTPUT_LEN);
+ tap_type *taps = fft::malloc_float(MAX_TAPS);
+
+ srandom(0); // we want reproducibility
+ memset(dline, 0, INPUT_LEN*sizeof(i_type));
+
+ for(int n = 0; n <= MAX_TAPS; n++) {
+ for(int ol = 0; ol <= OUTPUT_LEN; ol++) {
+
+ // build random test case
+ random_complex(input, INPUT_LEN);
+ random_floats(taps, MAX_TAPS);
+
+ // compute expected output values
+ memset(dline, 0, INPUT_LEN*sizeof(i_type));
+ for(int o = 0; o < (int)(ol/decimate); o++) {
+ // use an actual delay line for this test
+ for(int dd = 0; dd < (int)decimate; dd++) {
+ for(int oo = INPUT_LEN-1; oo > 0; oo--)
+ dline[oo] = dline[oo-1];
+ dline[0] = input[decimate*o+dd];
+ }
+ expected_output[o] = ref_dotprod(dline, taps, n);
+ }
+
+ // build filter
+ vector<tap_type> f1_taps(&taps[0], &taps[n]);
+ kernel::fir_filter_with_buffer_ccf *f1 = \
+ new kernel::fir_filter_with_buffer_ccf(f1_taps);
+
+ // zero the output, then do the filtering
+ memset(actual_output, 0, sizeof(actual_output));
+ f1->filterNdec(actual_output, input, ol/decimate, decimate);
+
+ // check results
+ //
+ // we use a sloppy error margin because on the x86 architecture,
+ // our reference implementation is using 80 bit floating point
+ // arithmetic, while the SSE version is using 32 bit float point
+ // arithmetic.
+
+ for(int o = 0; o < (int)(ol/decimate); o++) {
+ CPPUNIT_ASSERT_COMPLEXES_EQUAL(expected_output[o], actual_output[o],
+ sqrt((float)n)*0.25*MAX_DATA*MAX_DATA * ERR_DELTA);
+ }
+ delete f1;
+ }
+ }
+ fft::free(input);
+ fft::free(dline);
+ fft::free(expected_output);
+ fft::free(actual_output);
+ fft::free(taps);
+ }
+
+ } /* namespace ccf */
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/qa_fir_filter_with_buffer.h b/gr-filter/lib/qa_fir_filter_with_buffer.h
new file mode 100644
index 0000000000..8850ada20c
--- /dev/null
+++ b/gr-filter/lib/qa_fir_filter_with_buffer.h
@@ -0,0 +1,94 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_FIR_FILTER_WITH_BUFFER_H_
+#define _QA_FIR_FILTER_WITH_BUFFER_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+namespace gr {
+ namespace filter {
+
+ namespace fff {
+
+ class qa_fir_filter_with_buffer_fff : public CppUnit::TestCase
+ {
+ CPPUNIT_TEST_SUITE(qa_fir_filter_with_buffer_fff);
+ CPPUNIT_TEST(t1);
+ CPPUNIT_TEST(t2);
+ CPPUNIT_TEST(t3);
+ CPPUNIT_TEST_SUITE_END();
+
+ private:
+ void test_decimate(unsigned int decimate);
+
+ void t1();
+ void t2();
+ void t3();
+ };
+
+ } /* namespace fff */
+
+ namespace ccc {
+
+ class qa_fir_filter_with_buffer_ccc : public CppUnit::TestCase
+ {
+ CPPUNIT_TEST_SUITE(qa_fir_filter_with_buffer_ccc);
+ CPPUNIT_TEST(t1);
+ CPPUNIT_TEST(t2);
+ CPPUNIT_TEST(t3);
+ CPPUNIT_TEST_SUITE_END();
+
+ private:
+ void test_decimate(unsigned int decimate);
+
+ void t1();
+ void t2();
+ void t3();
+ };
+
+ } /* namespace ccc */
+
+ namespace ccf {
+
+ class qa_fir_filter_with_buffer_ccf : public CppUnit::TestCase
+ {
+ CPPUNIT_TEST_SUITE(qa_fir_filter_with_buffer_ccf);
+ CPPUNIT_TEST(t1);
+ CPPUNIT_TEST(t2);
+ CPPUNIT_TEST(t3);
+ CPPUNIT_TEST_SUITE_END();
+
+ private:
+ void test_decimate(unsigned int decimate);
+
+ void t1();
+ void t2();
+ void t3();
+ };
+
+ } /* namespace ccf */
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* _QA_FIR_FILTER_WITH_BUFFER_H_ */
diff --git a/gr-filter/lib/qa_firdes.cc b/gr-filter/lib/qa_firdes.cc
new file mode 100644
index 0000000000..c2fe399d5a
--- /dev/null
+++ b/gr-filter/lib/qa_firdes.cc
@@ -0,0 +1,621 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <qa_firdes.h>
+#include <filter/firdes.h>
+#include <cppunit/TestAssert.h>
+#include <gr_complex.h>
+#include <string.h>
+#include <iostream>
+#include <iomanip>
+#include <stdio.h>
+
+namespace gr {
+ namespace filter {
+
+#define NELEM(x) (sizeof(x) / sizeof(x[0]))
+
+ using std::vector;
+
+#if 0
+ static void
+ print_taps(std::ostream &s, vector<float> &v)
+ {
+
+ for(unsigned int i = 0; i < v.size(); i++) {
+ printf("tap[%2d] = %16.7e\n", i, v[i]);
+ }
+ }
+#endif
+
+ static void
+ check_symmetry(vector<float> &v)
+ {
+ int n = v.size();
+ int m = n / 2;
+
+ for(int i = 0; i < m; i++)
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(v[i], v[n - i - 1], 1e-9);
+ }
+
+ const static float t1_exp[53] = {
+ -9.0525491e-04,
+ 2.0713841e-04,
+ 1.2388536e-03,
+ 2.9683491e-04,
+ -1.7744775e-03,
+ -1.3599906e-03,
+ 2.2031884e-03,
+ 3.2744040e-03,
+ -1.8868084e-03,
+ -5.9935520e-03,
+ 6.4301129e-18,
+ 8.9516686e-03,
+ 4.2178580e-03,
+ -1.0998557e-02,
+ -1.1173409e-02,
+ 1.0455756e-02,
+ 2.0686293e-02,
+ -5.2032238e-03,
+ -3.1896964e-02,
+ -7.4998410e-03,
+ 4.3362070e-02,
+ 3.2502845e-02,
+ -5.3328082e-02,
+ -8.5621715e-02,
+ 6.0117975e-02,
+ 3.1128189e-01,
+ 4.3769023e-01,
+ 3.1128189e-01,
+ 6.0117975e-02,
+ -8.5621715e-02,
+ -5.3328082e-02,
+ 3.2502845e-02,
+ 4.3362070e-02,
+ -7.4998410e-03,
+ -3.1896964e-02,
+ -5.2032238e-03,
+ 2.0686293e-02,
+ 1.0455756e-02,
+ -1.1173409e-02,
+ -1.0998557e-02,
+ 4.2178580e-03,
+ 8.9516686e-03,
+ 6.4301129e-18,
+ -5.9935520e-03,
+ -1.8868084e-03,
+ 3.2744040e-03,
+ 2.2031884e-03,
+ -1.3599906e-03,
+ -1.7744775e-03,
+ 2.9683491e-04,
+ 1.2388536e-03,
+ 2.0713841e-04,
+ -9.0525491e-04
+ };
+
+ const static float t2_exp[53] = {
+ 9.0380036e-04,
+ -2.0680559e-04,
+ -1.2368630e-03,
+ -2.9635796e-04,
+ 1.7716263e-03,
+ 1.3578053e-03,
+ -2.1996482e-03,
+ -3.2691427e-03,
+ 1.8837767e-03,
+ 5.9839217e-03,
+ -6.4197810e-18,
+ -8.9372853e-03,
+ -4.2110807e-03,
+ 1.0980885e-02,
+ 1.1155456e-02,
+ -1.0438956e-02,
+ -2.0653054e-02,
+ 5.1948633e-03,
+ 3.1845711e-02,
+ 7.4877902e-03,
+ -4.3292396e-02,
+ -3.2450620e-02,
+ 5.3242393e-02,
+ 8.5484132e-02,
+ -6.0021374e-02,
+ -3.1078172e-01,
+ 5.6184036e-01,
+ -3.1078172e-01,
+ -6.0021374e-02,
+ 8.5484132e-02,
+ 5.3242393e-02,
+ -3.2450620e-02,
+ -4.3292396e-02,
+ 7.4877902e-03,
+ 3.1845711e-02,
+ 5.1948633e-03,
+ -2.0653054e-02,
+ -1.0438956e-02,
+ 1.1155456e-02,
+ 1.0980885e-02,
+ -4.2110807e-03,
+ -8.9372853e-03,
+ -6.4197810e-18,
+ 5.9839217e-03,
+ 1.8837767e-03,
+ -3.2691427e-03,
+ -2.1996482e-03,
+ 1.3578053e-03,
+ 1.7716263e-03,
+ -2.9635796e-04,
+ -1.2368630e-03,
+ -2.0680559e-04,
+ 9.0380036e-04
+ };
+
+ const static float t3_exp[107] = {
+ -1.8970841e-06,
+ -7.1057165e-04,
+ 5.4005696e-04,
+ 4.6233178e-04,
+ 2.0572044e-04,
+ 3.5209916e-04,
+ -1.4098573e-03,
+ 1.1279077e-04,
+ -6.2994129e-04,
+ 1.1450432e-03,
+ 1.3637283e-03,
+ -6.4360141e-04,
+ 3.6509900e-04,
+ -3.2864159e-03,
+ 7.0192874e-04,
+ 3.7524730e-04,
+ 2.0256115e-03,
+ 3.0641893e-03,
+ -3.6618244e-03,
+ 7.5592739e-05,
+ -5.5586505e-03,
+ 2.3849572e-03,
+ 4.0114378e-03,
+ 1.6636450e-03,
+ 4.7835698e-03,
+ -1.0191196e-02,
+ -3.8158931e-04,
+ -5.5551580e-03,
+ 5.3901658e-03,
+ 1.1366769e-02,
+ -3.0000482e-03,
+ 4.9341680e-03,
+ -2.0093076e-02,
+ 5.5752542e-17,
+ 1.2093617e-03,
+ 8.6089745e-03,
+ 2.2382140e-02,
+ -1.6854567e-02,
+ 1.6913920e-03,
+ -3.1222520e-02,
+ 3.2711059e-03,
+ 2.2604836e-02,
+ 8.1451107e-03,
+ 3.7583180e-02,
+ -5.2293688e-02,
+ -8.0551542e-03,
+ -4.0092729e-02,
+ 1.5582236e-02,
+ 9.7452506e-02,
+ -1.6183170e-02,
+ 8.3281815e-02,
+ -2.8196752e-01,
+ -1.0965768e-01,
+ 5.2867508e-01,
+ -1.0965768e-01,
+ -2.8196752e-01,
+ 8.3281815e-02,
+ -1.6183170e-02,
+ 9.7452506e-02,
+ 1.5582236e-02,
+ -4.0092729e-02,
+ -8.0551542e-03,
+ -5.2293688e-02,
+ 3.7583180e-02,
+ 8.1451107e-03,
+ 2.2604836e-02,
+ 3.2711059e-03,
+ -3.1222520e-02,
+ 1.6913920e-03,
+ -1.6854567e-02,
+ 2.2382140e-02,
+ 8.6089745e-03,
+ 1.2093617e-03,
+ 5.5752542e-17,
+ -2.0093076e-02,
+ 4.9341680e-03,
+ -3.0000482e-03,
+ 1.1366769e-02,
+ 5.3901658e-03,
+ -5.5551580e-03,
+ -3.8158931e-04,
+ -1.0191196e-02,
+ 4.7835698e-03,
+ 1.6636450e-03,
+ 4.0114378e-03,
+ 2.3849572e-03,
+ -5.5586505e-03,
+ 7.5592739e-05,
+ -3.6618244e-03,
+ 3.0641893e-03,
+ 2.0256115e-03,
+ 3.7524730e-04,
+ 7.0192874e-04,
+ -3.2864159e-03,
+ 3.6509900e-04,
+ -6.4360141e-04,
+ 1.3637283e-03,
+ 1.1450432e-03,
+ -6.2994129e-04,
+ 1.1279077e-04,
+ -1.4098573e-03,
+ 3.5209916e-04,
+ 2.0572044e-04,
+ 4.6233178e-04,
+ 5.4005696e-04,
+ -7.1057165e-04,
+ -1.8970841e-06
+ };
+
+ const static float t4_exp[] = { // low pass
+ 0.001059958362,
+ 0.0002263929928,
+ -0.001277606934,
+ -0.0009675776237,
+ 0.001592264394,
+ 0.00243603508,
+ -0.001451682881,
+ -0.004769335967,
+ 5.281541594e-18,
+ 0.007567512803,
+ 0.003658855334,
+ -0.009761494584,
+ -0.01011830103,
+ 0.009636915289,
+ 0.0193619132,
+ -0.004935568199,
+ -0.03060629964,
+ -0.007267376408,
+ 0.04236677289,
+ 0.03197422624,
+ -0.05274848267,
+ -0.0850463286,
+ 0.05989059806,
+ 0.31065014,
+ 0.4370569289,
+ 0.31065014,
+ 0.05989059806,
+ -0.0850463286,
+ -0.05274848267,
+ 0.03197422624,
+ 0.04236677289,
+ -0.007267376408,
+ -0.03060629964,
+ -0.004935568199,
+ 0.0193619132,
+ 0.009636915289,
+ -0.01011830103,
+ -0.009761494584,
+ 0.003658855334,
+ 0.007567512803,
+ 5.281541594e-18,
+ -0.004769335967,
+ -0.001451682881,
+ 0.00243603508,
+ 0.001592264394,
+ -0.0009675776237,
+ -0.001277606934,
+ 0.0002263929928,
+ 0.001059958362,
+ };
+
+ const static float t5_exp[] = { //high pass
+ -0.001062123571,
+ -0.0002268554381,
+ 0.001280216733,
+ 0.000969554123,
+ -0.001595516922,
+ -0.002441011136,
+ 0.001454648213,
+ 0.004779078532,
+ -5.292330097e-18,
+ -0.007582970895,
+ -0.00366632943,
+ 0.009781434201,
+ 0.01013896987,
+ -0.009656600654,
+ -0.01940146461,
+ 0.004945650231,
+ 0.03066881932,
+ 0.00728222169,
+ -0.04245331511,
+ -0.03203954175,
+ 0.05285623297,
+ 0.08522006124,
+ -0.06001294032,
+ -0.3112847209,
+ 0.5630782247,
+ -0.3112847209,
+ -0.06001294032,
+ 0.08522006124,
+ 0.05285623297,
+ -0.03203954175,
+ -0.04245331511,
+ 0.00728222169,
+ 0.03066881932,
+ 0.004945650231,
+ -0.01940146461,
+ -0.009656600654,
+ 0.01013896987,
+ 0.009781434201,
+ -0.00366632943,
+ -0.007582970895,
+ -5.292330097e-18,
+ 0.004779078532,
+ 0.001454648213,
+ -0.002441011136,
+ -0.001595516922,
+ 0.000969554123,
+ 0.001280216733,
+ -0.0002268554381,
+ -0.001062123571,
+ };
+
+ const static float t6_exp[] = { // bandpass
+ 0.0002809273137,
+ -0.001047327649,
+ 7.936541806e-05,
+ -0.0004270860809,
+ 0.0007595835486,
+ 0.0008966081077,
+ -0.0004236323002,
+ 0.0002423936094,
+ -0.002212299034,
+ 0.0004807534278,
+ 0.0002620361629,
+ 0.001443728455,
+ 0.002229931997,
+ -0.002720607212,
+ 5.731141573e-05,
+ -0.004297634587,
+ 0.001878833398,
+ 0.003217151389,
+ 0.001357055153,
+ 0.003965090029,
+ -0.008576190099,
+ -0.0003257228818,
+ -0.004805727862,
+ 0.004721920472,
+ 0.01007549558,
+ -0.002688719891,
+ 0.004467967432,
+ -0.01837076992,
+ 5.119658377e-17,
+ 0.001125075156,
+ 0.008071650751,
+ 0.02113764361,
+ -0.01602453552,
+ 0.001618095324,
+ -0.03004053794,
+ 0.003163811285,
+ 0.0219683405,
+ 0.007950295694,
+ 0.03682873398,
+ -0.05142467469,
+ -0.00794606097,
+ -0.03965795785,
+ 0.01544955093,
+ 0.09681399167,
+ -0.01610304788,
+ 0.08297294378,
+ -0.2811714709,
+ -0.1094062924,
+ 0.5275565982,
+ -0.1094062924,
+ -0.2811714709,
+ 0.08297294378,
+ -0.01610304788,
+ 0.09681399167,
+ 0.01544955093,
+ -0.03965795785,
+ -0.00794606097,
+ -0.05142467469,
+ 0.03682873398,
+ 0.007950295694,
+ 0.0219683405,
+ 0.003163811285,
+ -0.03004053794,
+ 0.001618095324,
+ -0.01602453552,
+ 0.02113764361,
+ 0.008071650751,
+ 0.001125075156,
+ 5.119658377e-17,
+ -0.01837076992,
+ 0.004467967432,
+ -0.002688719891,
+ 0.01007549558,
+ 0.004721920472,
+ -0.004805727862,
+ -0.0003257228818,
+ -0.008576190099,
+ 0.003965090029,
+ 0.001357055153,
+ 0.003217151389,
+ 0.001878833398,
+ -0.004297634587,
+ 5.731141573e-05,
+ -0.002720607212,
+ 0.002229931997,
+ 0.001443728455,
+ 0.0002620361629,
+ 0.0004807534278,
+ -0.002212299034,
+ 0.0002423936094,
+ -0.0004236323002,
+ 0.0008966081077,
+ 0.0007595835486,
+ -0.0004270860809,
+ 7.936541806e-05,
+ -0.001047327649,
+ 0.0002809273137,
+ };
+
+ void
+ qa_firdes::t1()
+ {
+ vector<float> taps =
+ firdes::low_pass(1.0,
+ 8000,
+ 1750,
+ 500,
+ 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_firdes::t2()
+ {
+ vector<float> taps =
+ firdes::high_pass(1.0,
+ 8000,
+ 1750,
+ 500,
+ 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_firdes::t3()
+ {
+ vector<float> taps =
+ firdes::band_pass(1.0,
+ 20e6,
+ 5.75e6 - (5.28e6/2),
+ 5.75e6 + (5.28e6/2),
+ 0.62e6,
+ 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_firdes::t4()
+ {
+ vector<float> taps =
+ firdes::low_pass_2(1.0,
+ 8000,
+ 1750,
+ 500,
+ 66,
+ firdes::WIN_HAMMING);
+
+ // std::cout << "ntaps: " << taps.size() << std::endl;
+ // print_taps(std::cout, taps);
+
+ CPPUNIT_ASSERT_EQUAL(NELEM(t4_exp), taps.size());
+ for(unsigned int i = 0; i < taps.size(); i++)
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(t4_exp[i], taps[i], 1e-9);
+
+ check_symmetry(taps);
+ }
+
+ void
+ qa_firdes::t5()
+ {
+ vector<float> taps =
+ firdes::high_pass_2(1.0,
+ 8000,
+ 1750,
+ 500,
+ 66,
+ firdes::WIN_HAMMING);
+
+ // std::cout << "ntaps: " << taps.size() << std::endl;
+ // print_taps(std::cout, taps);
+
+ CPPUNIT_ASSERT_EQUAL(NELEM(t5_exp), taps.size());
+
+ for(unsigned int i = 0; i < taps.size(); i++)
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(t5_exp[i], taps[i], 1e-9);
+
+ check_symmetry(taps);
+}
+
+ void
+ qa_firdes::t6()
+ {
+ vector<float> taps =
+ firdes::band_pass_2(1.0,
+ 20e6,
+ 5.75e6 - (5.28e6/2),
+ 5.75e6 + (5.28e6/2),
+ 0.62e6,
+ 66,
+ firdes::WIN_HAMMING);
+
+ // std::cout << "ntaps: " << taps.size() << std::endl;
+ // print_taps(std::cout, taps);
+
+ CPPUNIT_ASSERT_EQUAL(NELEM(t6_exp), taps.size());
+
+ for(unsigned int i = 0; i < taps.size(); i++)
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(t6_exp[i], taps[i], 1e-7);
+
+ check_symmetry(taps);
+ }
+
+ void
+ qa_firdes::t7()
+ {
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gnuradio-core/src/lib/general/gr_diff_decoder_bb.i b/gr-filter/lib/qa_firdes.h
index 3dddb17c3e..b27cf78b91 100644
--- a/gnuradio-core/src/lib/general/gr_diff_decoder_bb.i
+++ b/gr-filter/lib/qa_firdes.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2002,2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -19,13 +19,38 @@
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
+#ifndef _QA_FILTER_FIRDES_H_
+#define _QA_FILTER_FIRDES_H_
-GR_SWIG_BLOCK_MAGIC(gr,diff_decoder_bb)
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
-gr_diff_decoder_bb_sptr gr_make_diff_decoder_bb (unsigned int modulus);
+namespace gr {
+ namespace filter {
+
+ class qa_firdes : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE(qa_firdes);
+ CPPUNIT_TEST(t1);
+ CPPUNIT_TEST(t2);
+ CPPUNIT_TEST(t3);
+ CPPUNIT_TEST(t4);
+ CPPUNIT_TEST(t5);
+ CPPUNIT_TEST(t6);
+ CPPUNIT_TEST(t7);
+ CPPUNIT_TEST_SUITE_END();
+
+ private:
+ void t1();
+ void t2();
+ void t3();
+ void t4();
+ void t5();
+ void t6();
+ void t7();
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
-class gr_diff_decoder_bb : public gr_sync_block
-{
- private:
- gr_diff_decoder_bb (unsigned int modulus);
-};
+#endif /* _QA_FILTER_FIRDES_H_ */
diff --git a/gr-filter/lib/qa_mmse_fir_interpolator_cc.cc b/gr-filter/lib/qa_mmse_fir_interpolator_cc.cc
new file mode 100644
index 0000000000..268b8801cc
--- /dev/null
+++ b/gr-filter/lib/qa_mmse_fir_interpolator_cc.cc
@@ -0,0 +1,126 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2007,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/TestAssert.h>
+#include <qa_mmse_fir_interpolator_cc.h>
+#include <filter/mmse_fir_interpolator_cc.h>
+#include <fft/fft.h>
+#include <cstdio>
+#include <cmath>
+#include <stdexcept>
+#include <stdint.h>
+
+namespace gr {
+ namespace filter {
+
+ static float
+ test_fcn_sin(double index)
+ {
+ return (2 * sin (index * 0.25 * 2 * M_PI + 0.125 * M_PI)
+ + 3 * sin (index * 0.077 * 2 * M_PI + 0.3 * M_PI));
+ }
+
+ static float
+ test_fcn_cos(double index)
+ {
+ return (2 * cos (index * 0.25 * 2 * M_PI + 0.125 * M_PI)
+ + 3 * cos (index * 0.077 * 2 * M_PI + 0.3 * M_PI));
+ }
+
+ static gr_complex
+ test_fcn(double index)
+ {
+ return gr_complex(test_fcn_cos(index), test_fcn_sin(index));
+ }
+
+
+ void
+ qa_mmse_fir_interpolator_cc::t1()
+ {
+ static const unsigned N = 100;
+ gr_complex *input = fft::malloc_complex(N + 10);
+
+ for(unsigned i = 0; i < N+10; i++)
+ input[i] = test_fcn((double) i);
+
+ mmse_fir_interpolator_cc intr;
+ float inv_nsteps = 1.0 / intr.nsteps();
+
+ for(unsigned i = 0; i < N; i++) {
+ for(unsigned imu = 0; imu <= intr.nsteps (); imu += 1) {
+ gr_complex expected = test_fcn((i + 3) + imu * inv_nsteps);
+ gr_complex actual = intr.interpolate(&input[i], imu * inv_nsteps);
+
+ CPPUNIT_ASSERT_COMPLEXES_EQUAL(expected, actual, 0.004);
+ // printf ("%9.6f %9.6f %9.6f\n", expected, actual, expected - actual);
+ }
+ }
+ fft::free(input);
+ }
+
+ /*
+ * Force bad alignment and confirm that it raises an exception
+ */
+ void
+ qa_mmse_fir_interpolator_cc::t2_body()
+ {
+ static const unsigned N = 100;
+ float float_input[2*(N+10) + 1];
+ gr_complex *input;
+
+ // We require that gr_complex be aligned on an 8-byte boundary.
+ // Ensure that we ARE NOT ;)
+
+ if(((intptr_t) float_input & 0x7) == 0)
+ input = reinterpret_cast<gr_complex *>(&float_input[1]);
+ else
+ input = reinterpret_cast<gr_complex *>(&float_input[0]);
+
+ for(unsigned i = 0; i < (N+10); i++)
+ input[i] = test_fcn((double) i);
+
+ mmse_fir_interpolator_cc intr;
+ float inv_nsteps = 1.0 / intr.nsteps();
+
+ for(unsigned i = 0; i < N; i++) {
+ for(unsigned imu = 0; imu <= intr.nsteps (); imu += 1) {
+ gr_complex expected = test_fcn((i + 3) + imu * inv_nsteps);
+ gr_complex actual = intr.interpolate(&input[i], imu * inv_nsteps);
+
+ CPPUNIT_ASSERT_COMPLEXES_EQUAL(expected, actual, 0.004);
+ // printf ("%9.6f %9.6f %9.6f\n", expected, actual, expected - actual);
+ }
+ }
+ }
+
+ void
+ qa_mmse_fir_interpolator_cc::t2()
+ {
+ CPPUNIT_ASSERT_THROW(t2_body(), std::invalid_argument);
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/qa_mmse_fir_interpolator_cc.h b/gr-filter/lib/qa_mmse_fir_interpolator_cc.h
new file mode 100644
index 0000000000..a45965ca27
--- /dev/null
+++ b/gr-filter/lib/qa_mmse_fir_interpolator_cc.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2007,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _QA_MMSE_FIR_INTERPOLATOR_CC_H_
+#define _QA_MMSE_FIR_INTERPOLATOR_CC_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+namespace gr {
+ namespace filter {
+
+ class qa_mmse_fir_interpolator_cc : public CppUnit::TestCase
+ {
+ CPPUNIT_TEST_SUITE(qa_mmse_fir_interpolator_cc);
+ CPPUNIT_TEST(t1);
+ // CPPUNIT_TEST(t2);
+ CPPUNIT_TEST_SUITE_END();
+
+ private:
+ void t1();
+ void t2();
+ void t2_body();
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* _QA_MMSE_FIR_INTERPOLATOR_CC_H_ */
diff --git a/gr-filter/lib/qa_mmse_fir_interpolator_ff.cc b/gr-filter/lib/qa_mmse_fir_interpolator_ff.cc
new file mode 100644
index 0000000000..54387fd9bd
--- /dev/null
+++ b/gr-filter/lib/qa_mmse_fir_interpolator_ff.cc
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/TestAssert.h>
+#include <qa_mmse_fir_interpolator_ff.h>
+#include <filter/mmse_fir_interpolator_ff.h>
+#include <fft/fft.h>
+#include <cstdio>
+#include <cmath>
+
+namespace gr {
+ namespace filter {
+
+ 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_mmse_fir_interpolator_ff::t1()
+ {
+ // use aligned malloc and make sure that everything in this
+ // buffer is properly initialized.
+ static const unsigned N = 100;
+ float *input = fft::malloc_float(N + 10);
+
+ for(unsigned i = 0; i < N+10; i++)
+ input[i] = test_fcn((double) i);
+
+ mmse_fir_interpolator_ff 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);
+ }
+ }
+ fft::free(input);
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gnuradio-core/src/lib/general/qa_gri_lfsr.h b/gr-filter/lib/qa_mmse_fir_interpolator_ff.h
index e91843bbb3..833ec173ac 100644
--- a/gnuradio-core/src/lib/general/qa_gri_lfsr.h
+++ b/gr-filter/lib/qa_mmse_fir_interpolator_ff.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2002,2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -19,24 +19,27 @@
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
-#ifndef _QA_GRI_LFSR_H_
-#define _QA_GRI_LFSR_H_
+
+#ifndef _QA_MMSE_FIR_INTERPOLATOR_FF_H_
+#define _QA_MMSE_FIR_INTERPOLATOR_FF_H_
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestCase.h>
-class qa_gri_lfsr : public CppUnit::TestCase {
+namespace gr {
+ namespace filter {
+
+ class qa_mmse_fir_interpolator_ff : public CppUnit::TestCase
+ {
+ CPPUNIT_TEST_SUITE(qa_mmse_fir_interpolator_ff);
+ CPPUNIT_TEST(t1);
+ CPPUNIT_TEST_SUITE_END();
- CPPUNIT_TEST_SUITE(qa_gri_lfsr);
- CPPUNIT_TEST(test_lfsr);
- CPPUNIT_TEST(test_scrambler);
- CPPUNIT_TEST(test_descrambler);
- CPPUNIT_TEST_SUITE_END();
+ private:
+ void t1();
+ };
- private:
- void test_lfsr();
- void test_scrambler();
- void test_descrambler();
-};
+ } /* namespace filter */
+} /* namespace gr */
-#endif /* _QA_GRI_LFSR_H_ */
+#endif /* _QA_MMSE_FIR_INTERPOLATOR_FF_H_ */
diff --git a/gr-filter/lib/rational_resampler_base_XXX_impl.cc.t b/gr-filter/lib/rational_resampler_base_XXX_impl.cc.t
new file mode 100644
index 0000000000..2e9161eeb8
--- /dev/null
+++ b/gr-filter/lib/rational_resampler_base_XXX_impl.cc.t
@@ -0,0 +1,174 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/* @WARNING@ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "@IMPL_NAME@.h"
+#include <gr_io_signature.h>
+#include <volk/volk.h>
+#include <stdexcept>
+
+namespace gr {
+ namespace filter {
+
+ @BASE_NAME@::sptr
+ @BASE_NAME@::make(unsigned interpolation,
+ unsigned decimation,
+ const std::vector<@TAP_TYPE@> &taps)
+ {
+ return gnuradio::get_initial_sptr
+ (new @IMPL_NAME@(interpolation, decimation, taps));
+ }
+
+ @IMPL_NAME@::@IMPL_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_firs(interpolation),
+ d_updated(false)
+ {
+ if(interpolation == 0)
+ throw std::out_of_range("@IMPL_NAME@: interpolation must be > 0");
+ if(decimation == 0)
+ throw std::out_of_range("@IMPL_NAME@: 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] = new kernel::@FIR_TYPE@(1, dummy_taps);
+ }
+
+ set_taps(taps);
+ install_taps(d_new_taps);
+ }
+
+ @IMPL_NAME@::~@IMPL_NAME@()
+ {
+ int interp = interpolation();
+ for(int i = 0; i < interp; i++) {
+ delete d_firs[i];
+ }
+ }
+
+ void
+ @IMPL_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
+ @IMPL_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;
+ }
+
+ std::vector<@TAP_TYPE@>
+ @IMPL_NAME@::taps() const
+ {
+ return d_new_taps;
+ }
+
+ void
+ @IMPL_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
+ @IMPL_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;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/rational_resampler_base_XXX_impl.h.t b/gr-filter/lib/rational_resampler_base_XXX_impl.h.t
new file mode 100644
index 0000000000..4396656da2
--- /dev/null
+++ b/gr-filter/lib/rational_resampler_base_XXX_impl.h.t
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/* @WARNING@ */
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <filter/fir_filter.h>
+#include <filter/@BASE_NAME@.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API @IMPL_NAME@ : public @BASE_NAME@
+ {
+ private:
+ unsigned d_history;
+ unsigned d_interpolation;
+ unsigned d_decimation;
+ unsigned d_ctr;
+ std::vector<@TAP_TYPE@> d_new_taps;
+ std::vector<kernel::@FIR_TYPE@ *> d_firs;
+ bool d_updated;
+
+ void install_taps(const std::vector<@TAP_TYPE@> &taps);
+
+ public:
+ @IMPL_NAME@(unsigned interpolation, unsigned decimation,
+ const std::vector<@TAP_TYPE@> &taps);
+
+ ~@IMPL_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);
+ std::vector<@TAP_TYPE@> taps() const;
+
+ 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);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* @GUARD_NAME@ */
diff --git a/gr-filter/lib/single_pole_iir_filter_cc_impl.cc b/gr-filter/lib/single_pole_iir_filter_cc_impl.cc
new file mode 100644
index 0000000000..9406f2c98a
--- /dev/null
+++ b/gr-filter/lib/single_pole_iir_filter_cc_impl.cc
@@ -0,0 +1,89 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "single_pole_iir_filter_cc_impl.h"
+#include <gr_io_signature.h>
+
+
+namespace gr {
+ namespace filter {
+
+ single_pole_iir_filter_cc::sptr
+ single_pole_iir_filter_cc::make(double alpha, unsigned int vlen)
+ {
+ return gnuradio::get_initial_sptr
+ (new single_pole_iir_filter_cc_impl(alpha, vlen));
+ }
+
+ single_pole_iir_filter_cc_impl::single_pole_iir_filter_cc_impl
+ (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);
+ }
+
+ single_pole_iir_filter_cc_impl::~single_pole_iir_filter_cc_impl()
+ {
+ }
+
+ void
+ single_pole_iir_filter_cc_impl::set_taps(double alpha)
+ {
+ for(unsigned int i = 0; i < d_vlen; i++) {
+ d_iir[i].set_taps(alpha);
+ }
+ }
+
+ int
+ single_pole_iir_filter_cc_impl::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;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/single_pole_iir_filter_cc_impl.h b/gr-filter/lib/single_pole_iir_filter_cc_impl.h
new file mode 100644
index 0000000000..fa627881e5
--- /dev/null
+++ b/gr-filter/lib/single_pole_iir_filter_cc_impl.h
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004-2006,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_SINGLE_POLE_IIR_FILTER_CC_IMPL_H
+#define INCLUDED_SINGLE_POLE_IIR_FILTER_CC_IMPL_H
+
+#include <filter/single_pole_iir.h>
+#include <filter/single_pole_iir_filter_cc.h>
+#include <gr_sync_block.h>
+#include <gr_complex.h>
+#include <stdexcept>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API single_pole_iir_filter_cc_impl : public single_pole_iir_filter_cc
+ {
+ private:
+ unsigned int d_vlen;
+ std::vector<single_pole_iir<gr_complex,gr_complex,double> > d_iir;
+
+ public:
+ single_pole_iir_filter_cc_impl(double alpha, unsigned int vlen);
+ ~single_pole_iir_filter_cc_impl();
+
+ void set_taps(double alpha);
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_SINGLE_POLE_IIR_FILTER_CC_IMPL_H */
diff --git a/gr-filter/lib/single_pole_iir_filter_ff_impl.cc b/gr-filter/lib/single_pole_iir_filter_ff_impl.cc
new file mode 100644
index 0000000000..7e2bae5db7
--- /dev/null
+++ b/gr-filter/lib/single_pole_iir_filter_ff_impl.cc
@@ -0,0 +1,87 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "single_pole_iir_filter_ff_impl.h"
+#include <gr_io_signature.h>
+
+namespace gr {
+ namespace filter {
+
+ single_pole_iir_filter_ff::sptr
+ single_pole_iir_filter_ff::make(double alpha, unsigned int vlen)
+ {
+ return gnuradio::get_initial_sptr
+ (new single_pole_iir_filter_ff_impl(alpha, vlen));
+ }
+
+ single_pole_iir_filter_ff_impl::single_pole_iir_filter_ff_impl
+ (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);
+ }
+
+ single_pole_iir_filter_ff_impl::~single_pole_iir_filter_ff_impl()
+ {
+ }
+
+ void
+ single_pole_iir_filter_ff_impl::set_taps(double alpha)
+ {
+ for(unsigned int i = 0; i < d_vlen; i++) {
+ d_iir[i].set_taps(alpha);
+ }
+ }
+
+ int
+ single_pole_iir_filter_ff_impl::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;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/single_pole_iir_filter_ff_impl.h b/gr-filter/lib/single_pole_iir_filter_ff_impl.h
new file mode 100644
index 0000000000..cba9c188c2
--- /dev/null
+++ b/gr-filter/lib/single_pole_iir_filter_ff_impl.h
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004-2006,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_SINGLE_POLE_IIR_FILTER_FF_IMPL_H
+#define INCLUDED_SINGLE_POLE_IIR_FILTER_FF_IMPL_H
+
+#include <filter/single_pole_iir.h>
+#include <filter/single_pole_iir_filter_ff.h>
+#include <gr_sync_block.h>
+#include <stdexcept>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API single_pole_iir_filter_ff_impl : public single_pole_iir_filter_ff
+ {
+ private:
+ unsigned int d_vlen;
+ std::vector<single_pole_iir<float,float,double> > d_iir;
+
+ public:
+ single_pole_iir_filter_ff_impl(double alpha, unsigned int vlen);
+ ~single_pole_iir_filter_ff_impl();
+
+ void set_taps(double alpha);
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_SINGLE_POLE_IIR_FILTER_FF_IMPL_H */
diff --git a/gnuradio-core/src/lib/general/gr_packet_sink.i b/gr-filter/lib/test_gr_filter.cc
index d1290f9d39..915b6286bd 100644
--- a/gnuradio-core/src/lib/general/gr_packet_sink.i
+++ b/gr-filter/lib/test_gr_filter.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -20,22 +20,24 @@
* Boston, MA 02110-1301, USA.
*/
-GR_SWIG_BLOCK_MAGIC(gr,packet_sink)
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/XmlOutputter.h>
-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
- );
+#include <gr_unittests.h>
+#include <qa_filter.h>
+#include <iostream>
-class gr_packet_sink : public gr_sync_block
+int
+main (int argc, char **argv)
{
- protected:
- gr_packet_sink (const std::vector<unsigned char>& sync_vector,
- gr_msg_queue_sptr target_queue,
- int threshold);
- public:
- ~gr_packet_sink ();
+ CppUnit::TextTestRunner runner;
+ std::ofstream xmlfile(get_unittest_path("gr_filter.xml").c_str());
+ CppUnit::XmlOutputter *xmlout = new CppUnit::XmlOutputter(&runner.result(), xmlfile);
- bool carrier_sensed() const;
-};
+ runner.addTest(qa_gr_filter::suite());
+ runner.setOutputter(xmlout);
+
+ bool was_successful = runner.run("", false);
+
+ return was_successful ? 0 : 1;
+}
diff --git a/gr-filter/python/CMakeLists.txt b/gr-filter/python/CMakeLists.txt
new file mode 100644
index 0000000000..07f03fac4c
--- /dev/null
+++ b/gr-filter/python/CMakeLists.txt
@@ -0,0 +1,50 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+include(GrPython)
+
+GR_PYTHON_INSTALL(
+ FILES
+ __init__.py
+ optfir.py
+ pfb.py
+ rational_resampler.py
+ DESTINATION ${GR_PYTHON_DIR}/gnuradio/filter
+ COMPONENT "filter_python"
+)
+
+########################################################################
+# Handle the unit tests
+########################################################################
+if(ENABLE_TESTING)
+include(GrTest)
+file(GLOB py_qa_test_files "qa_*.py")
+foreach(py_qa_test_file ${py_qa_test_files})
+ get_filename_component(py_qa_test_name ${py_qa_test_file} NAME_WE)
+ set(GR_TEST_PYTHON_DIRS
+ ${CMAKE_BINARY_DIR}/gnuradio-core/src/python
+ ${CMAKE_BINARY_DIR}/gnuradio-core/src/lib/swig
+ ${CMAKE_BINARY_DIR}/gr-filter/python
+ ${CMAKE_BINARY_DIR}/gr-filter/swig
+ )
+ set(GR_TEST_TARGET_DEPS gruel gnuradio-core gnuradio-filter)
+ GR_ADD_TEST(${py_qa_test_name} ${PYTHON_EXECUTABLE} ${py_qa_test_file})
+endforeach(py_qa_test_file)
+endif(ENABLE_TESTING)
diff --git a/gr-filter/python/__init__.py b/gr-filter/python/__init__.py
new file mode 100644
index 0000000000..65a62d828d
--- /dev/null
+++ b/gr-filter/python/__init__.py
@@ -0,0 +1,30 @@
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+'''
+This is the gr-filter package. This package provides GNU Radio
+processing blocks for FILTER and related functions.
+'''
+
+from filter_swig import *
+from rational_resampler import *
+import pfb
+import optfir
diff --git a/gr-filter/python/optfir.py b/gr-filter/python/optfir.py
new file mode 100644
index 0000000000..bccb8c68d0
--- /dev/null
+++ b/gr-filter/python/optfir.py
@@ -0,0 +1,339 @@
+#
+# Copyright 2004,2005,2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+'''
+Routines for designing optimal FIR filters.
+
+For a great intro to how all this stuff works, see section 6.6 of
+"Digital Signal Processing: A Practical Approach", Emmanuael C. Ifeachor
+and Barrie W. Jervis, Adison-Wesley, 1993. ISBN 0-201-54413-X.
+'''
+
+import math, cmath
+import filter_swig as filter
+
+# ----------------------------------------------------------------
+
+## Builds a low pass filter.
+# @param gain Filter gain in the passband (linear)
+# @param Fs Sampling rate (sps)
+# @param freq1 End of pass band (in Hz)
+# @param freq2 Start of stop band (in Hz)
+# @param passband_ripple_db Pass band ripple in dB (should be small, < 1)
+# @param stopband_atten_db Stop band attenuation in dB (should be large, >= 60)
+# @param nextra_taps Extra taps to use in the filter (default=2)
+def low_pass (gain, Fs, freq1, freq2, passband_ripple_db, stopband_atten_db,
+ nextra_taps=2):
+ passband_dev = passband_ripple_to_dev (passband_ripple_db)
+ stopband_dev = stopband_atten_to_dev (stopband_atten_db)
+ desired_ampls = (gain, 0)
+ (n, fo, ao, w) = remezord ([freq1, freq2], desired_ampls,
+ [passband_dev, stopband_dev], Fs)
+ # The remezord typically under-estimates the filter order, so add 2 taps by default
+ taps = filter.pm_remez (n + nextra_taps, fo, ao, w, "bandpass")
+ return taps
+
+## Builds a band pass filter.
+# @param gain Filter gain in the passband (linear)
+# @param Fs Sampling rate (sps)
+# @param freq_sb1 End of stop band (in Hz)
+# @param freq_pb1 Start of pass band (in Hz)
+# @param freq_pb2 End of pass band (in Hz)
+# @param freq_sb2 Start of stop band (in Hz)
+# @param passband_ripple_db Pass band ripple in dB (should be small, < 1)
+# @param stopband_atten_db Stop band attenuation in dB (should be large, >= 60)
+# @param nextra_taps Extra taps to use in the filter (default=2)
+def band_pass (gain, Fs, freq_sb1, freq_pb1, freq_pb2, freq_sb2,
+ passband_ripple_db, stopband_atten_db,
+ nextra_taps=2):
+ passband_dev = passband_ripple_to_dev (passband_ripple_db)
+ stopband_dev = stopband_atten_to_dev (stopband_atten_db)
+ desired_ampls = (0, gain, 0)
+ desired_freqs = [freq_sb1, freq_pb1, freq_pb2, freq_sb2]
+ desired_ripple = [stopband_dev, passband_dev, stopband_dev]
+ (n, fo, ao, w) = remezord (desired_freqs, desired_ampls,
+ desired_ripple, Fs)
+ # The remezord typically under-estimates the filter order, so add 2 taps by default
+ taps = filter.pm_remez (n + nextra_taps, fo, ao, w, "bandpass")
+ return taps
+
+
+## Builds a band pass filter with complex taps by making an LPF and
+# spinning it up to the right center frequency
+# @param gain Filter gain in the passband (linear)
+# @param Fs Sampling rate (sps)
+# @param freq_sb1 End of stop band (in Hz)
+# @param freq_pb1 Start of pass band (in Hz)
+# @param freq_pb2 End of pass band (in Hz)
+# @param freq_sb2 Start of stop band (in Hz)
+# @param passband_ripple_db Pass band ripple in dB (should be small, < 1)
+# @param stopband_atten_db Stop band attenuation in dB (should be large, >= 60)
+# @param nextra_taps Extra taps to use in the filter (default=2)
+def complex_band_pass (gain, Fs, freq_sb1, freq_pb1, freq_pb2, freq_sb2,
+ passband_ripple_db, stopband_atten_db,
+ nextra_taps=2):
+ center_freq = (freq_pb2 + freq_pb1) / 2.0
+ lp_pb = (freq_pb2 - center_freq)/1.0
+ lp_sb = freq_sb2 - center_freq
+ lptaps = low_pass(gain, Fs, lp_pb, lp_sb, passband_ripple_db,
+ stopband_atten_db, nextra_taps)
+ spinner = [cmath.exp(2j*cmath.pi*center_freq/Fs*i) for i in xrange(len(lptaps))]
+ taps = [s*t for s,t in zip(spinner, lptaps)]
+ return taps
+
+
+## Builds a band reject filter
+# spinning it up to the right center frequency
+# @param gain Filter gain in the passband (linear)
+# @param Fs Sampling rate (sps)
+# @param freq_pb1 End of pass band (in Hz)
+# @param freq_sb1 Start of stop band (in Hz)
+# @param freq_sb2 End of stop band (in Hz)
+# @param freq_pb2 Start of pass band (in Hz)
+# @param passband_ripple_db Pass band ripple in dB (should be small, < 1)
+# @param stopband_atten_db Stop band attenuation in dB (should be large, >= 60)
+# @param nextra_taps Extra taps to use in the filter (default=2)
+def band_reject (gain, Fs, freq_pb1, freq_sb1, freq_sb2, freq_pb2,
+ passband_ripple_db, stopband_atten_db,
+ nextra_taps=2):
+ passband_dev = passband_ripple_to_dev (passband_ripple_db)
+ stopband_dev = stopband_atten_to_dev (stopband_atten_db)
+ desired_ampls = (gain, 0, gain)
+ desired_freqs = [freq_pb1, freq_sb1, freq_sb2, freq_pb2]
+ desired_ripple = [passband_dev, stopband_dev, passband_dev]
+ (n, fo, ao, w) = remezord (desired_freqs, desired_ampls,
+ desired_ripple, Fs)
+ # Make sure we use an odd number of taps
+ if((n+nextra_taps)%2 == 1):
+ n += 1
+ # The remezord typically under-estimates the filter order, so add 2 taps by default
+ taps = filter.pm_remez (n + nextra_taps, fo, ao, w, "bandpass")
+ return taps
+
+
+## Builds a high pass filter.
+# @param gain Filter gain in the passband (linear)
+# @param Fs Sampling rate (sps)
+# @param freq1 End of stop band (in Hz)
+# @param freq2 Start of pass band (in Hz)
+# @param passband_ripple_db Pass band ripple in dB (should be small, < 1)
+# @param stopband_atten_db Stop band attenuation in dB (should be large, >= 60)
+# @param nextra_taps Extra taps to use in the filter (default=2)
+def high_pass (gain, Fs, freq1, freq2, passband_ripple_db, stopband_atten_db,
+ nextra_taps=2):
+ passband_dev = passband_ripple_to_dev (passband_ripple_db)
+ stopband_dev = stopband_atten_to_dev (stopband_atten_db)
+ desired_ampls = (0, 1)
+ (n, fo, ao, w) = remezord ([freq1, freq2], desired_ampls,
+ [stopband_dev, passband_dev], Fs)
+ # For a HPF, we need to use an odd number of taps
+ # In filter.remez, ntaps = n+1, so n must be even
+ if((n+nextra_taps)%2 == 1):
+ n += 1
+
+ # The remezord typically under-estimates the filter order, so add 2 taps by default
+ taps = filter.pm_remez (n + nextra_taps, fo, ao, w, "bandpass")
+ return taps
+
+# ----------------------------------------------------------------
+
+def stopband_atten_to_dev (atten_db):
+ """Convert a stopband attenuation in dB to an absolute value"""
+ return 10**(-atten_db/20)
+
+def passband_ripple_to_dev (ripple_db):
+ """Convert passband ripple spec expressed in dB to an absolute value"""
+ return (10**(ripple_db/20)-1)/(10**(ripple_db/20)+1)
+
+# ----------------------------------------------------------------
+
+def remezord (fcuts, mags, devs, fsamp = 2):
+ '''
+ FIR order estimator (lowpass, highpass, bandpass, mulitiband).
+
+ (n, fo, ao, w) = remezord (f, a, dev)
+ (n, fo, ao, w) = remezord (f, a, dev, fs)
+
+ (n, fo, ao, w) = remezord (f, a, dev) finds the approximate order,
+ normalized frequency band edges, frequency band amplitudes, and
+ weights that meet input specifications f, a, and dev, to use with
+ the remez command.
+
+ * f is a sequence of frequency band edges (between 0 and Fs/2, where
+ Fs is the sampling frequency), and a is a sequence specifying the
+ desired amplitude on the bands defined by f. The length of f is
+ twice the length of a, minus 2. The desired function is
+ piecewise constant.
+
+ * dev is a sequence the same size as a that specifies the maximum
+ allowable deviation or ripples between the frequency response
+ and the desired amplitude of the output filter, for each band.
+
+ Use remez with the resulting order n, frequency sequence fo,
+ amplitude response sequence ao, and weights w to design the filter b
+ which approximately meets the specifications given by remezord
+ input parameters f, a, and dev:
+
+ b = remez (n, fo, ao, w)
+
+ (n, fo, ao, w) = remezord (f, a, dev, Fs) specifies a sampling frequency Fs.
+
+ Fs defaults to 2 Hz, implying a Nyquist frequency of 1 Hz. You can
+ therefore specify band edges scaled to a particular applications
+ sampling frequency.
+
+ In some cases remezord underestimates the order n. If the filter
+ does not meet the specifications, try a higher order such as n+1
+ or n+2.
+ '''
+ # get local copies
+ fcuts = fcuts[:]
+ mags = mags[:]
+ devs = devs[:]
+
+ for i in range (len (fcuts)):
+ fcuts[i] = float (fcuts[i]) / fsamp
+
+ nf = len (fcuts)
+ nm = len (mags)
+ nd = len (devs)
+ nbands = nm
+
+ if nm != nd:
+ raise ValueError, "Length of mags and devs must be equal"
+
+ if nf != 2 * (nbands - 1):
+ raise ValueError, "Length of f must be 2 * len (mags) - 2"
+
+ for i in range (len (mags)):
+ if mags[i] != 0: # if not stopband, get relative deviation
+ devs[i] = devs[i] / mags[i]
+
+ # separate the passband and stopband edges
+ f1 = fcuts[0::2]
+ f2 = fcuts[1::2]
+
+ n = 0
+ min_delta = 2
+ for i in range (len (f1)):
+ if f2[i] - f1[i] < min_delta:
+ n = i
+ min_delta = f2[i] - f1[i]
+
+ if nbands == 2:
+ # lowpass or highpass case (use formula)
+ l = lporder (f1[n], f2[n], devs[0], devs[1])
+ else:
+ # bandpass or multipass case
+ # try different lowpasses and take the worst one that
+ # goes through the BP specs
+ l = 0
+ for i in range (1, nbands-1):
+ l1 = lporder (f1[i-1], f2[i-1], devs[i], devs[i-1])
+ l2 = lporder (f1[i], f2[i], devs[i], devs[i+1])
+ l = max (l, l1, l2)
+
+ n = int (math.ceil (l)) - 1 # need order, not length for remez
+
+ # cook up remez compatible result
+ ff = [0] + fcuts + [1]
+ for i in range (1, len (ff) - 1):
+ ff[i] *= 2
+
+ aa = []
+ for a in mags:
+ aa = aa + [a, a]
+
+ max_dev = max (devs)
+ wts = [1] * len(devs)
+ for i in range (len (wts)):
+ wts[i] = max_dev / devs[i]
+
+ return (n, ff, aa, wts)
+
+# ----------------------------------------------------------------
+
+def lporder (freq1, freq2, delta_p, delta_s):
+ '''
+ FIR lowpass filter length estimator. freq1 and freq2 are
+ normalized to the sampling frequency. delta_p is the passband
+ deviation (ripple), delta_s is the stopband deviation (ripple).
+
+ Note, this works for high pass filters too (freq1 > freq2), but
+ doesnt work well if the transition is near f == 0 or f == fs/2
+
+ From Herrmann et al (1973), Practical design rules for optimum
+ finite impulse response filters. Bell System Technical J., 52, 769-99
+ '''
+ df = abs (freq2 - freq1)
+ ddp = math.log10 (delta_p)
+ dds = math.log10 (delta_s)
+
+ a1 = 5.309e-3
+ a2 = 7.114e-2
+ a3 = -4.761e-1
+ a4 = -2.66e-3
+ a5 = -5.941e-1
+ a6 = -4.278e-1
+
+ b1 = 11.01217
+ b2 = 0.5124401
+
+ t1 = a1 * ddp * ddp
+ t2 = a2 * ddp
+ t3 = a4 * ddp * ddp
+ t4 = a5 * ddp
+
+ dinf=((t1 + t2 + a3) * dds) + (t3 + t4 + a6)
+ ff = b1 + b2 * (ddp - dds)
+ n = dinf / df - ff * df + 1
+ return n
+
+
+def bporder (freq1, freq2, delta_p, delta_s):
+ '''
+ FIR bandpass filter length estimator. freq1 and freq2 are
+ normalized to the sampling frequency. delta_p is the passband
+ deviation (ripple), delta_s is the stopband deviation (ripple).
+
+ From Mintzer and Liu (1979)
+ '''
+ df = abs (freq2 - freq1)
+ ddp = math.log10 (delta_p)
+ dds = math.log10 (delta_s)
+
+ a1 = 0.01201
+ a2 = 0.09664
+ a3 = -0.51325
+ a4 = 0.00203
+ a5 = -0.57054
+ a6 = -0.44314
+
+ t1 = a1 * ddp * ddp
+ t2 = a2 * ddp
+ t3 = a4 * ddp * ddp
+ t4 = a5 * ddp
+
+ cinf = dds * (t1 + t2 + a3) + t3 + t4 + a6
+ ginf = -14.6 * math.log10 (delta_p / delta_s) - 16.9
+ n = cinf / df + ginf * df + 1
+ return n
+
diff --git a/gr-filter/python/pfb.py b/gr-filter/python/pfb.py
new file mode 100644
index 0000000000..ddf2899826
--- /dev/null
+++ b/gr-filter/python/pfb.py
@@ -0,0 +1,271 @@
+#!/usr/bin/env python
+#
+# Copyright 2009,2010,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr
+import filter_swig as filter
+import optfir
+
+class channelizer_ccf(gr.hier_block2):
+ '''
+ Make a Polyphase Filter channelizer (complex in, complex out, floating-point taps)
+
+ This simplifies the interface by allowing a single input stream to connect to this block.
+ It will then output a stream for each channel.
+ '''
+ def __init__(self, numchans, taps=None, oversample_rate=1, atten=100):
+ gr.hier_block2.__init__(self, "pfb_channelizer_ccf",
+ gr.io_signature(1, 1, gr.sizeof_gr_complex),
+ gr.io_signature(numchans, numchans, gr.sizeof_gr_complex))
+
+ self._nchans = numchans
+ self._oversample_rate = oversample_rate
+
+ if taps is not None:
+ self._taps = taps
+ else:
+ # Create a filter that covers the full bandwidth of the input signal
+ bw = 0.4
+ tb = 0.2
+ ripple = 0.1
+ made = False
+ while not made:
+ try:
+ self._taps = optfir.low_pass(1, self._nchans, bw, bw+tb, ripple, atten)
+ made = True
+ except RuntimeError:
+ ripple += 0.01
+ made = False
+ print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple))
+
+ # Build in an exit strategy; if we've come this far, it ain't working.
+ if(ripple >= 1.0):
+ raise RuntimeError("optfir could not generate an appropriate filter.")
+
+ self.s2ss = gr.stream_to_streams(gr.sizeof_gr_complex, self._nchans)
+ self.pfb = filter.pfb_channelizer_ccf(self._nchans, self._taps,
+ self._oversample_rate)
+ self.connect(self, self.s2ss)
+
+ for i in xrange(self._nchans):
+ self.connect((self.s2ss,i), (self.pfb,i))
+ self.connect((self.pfb,i), (self,i))
+
+ def set_channel_map(self, newmap):
+ self.pfb.set_channel_map(newmap)
+
+
+
+class interpolator_ccf(gr.hier_block2):
+ '''
+ Make a Polyphase Filter interpolator (complex in, complex out, floating-point taps)
+
+ The block takes a single complex stream in and outputs a single complex
+ stream out. As such, it requires no extra glue to handle the input/output
+ streams. This block is provided to be consistent with the interface to the
+ other PFB block.
+ '''
+ def __init__(self, interp, taps=None, atten=100):
+ gr.hier_block2.__init__(self, "pfb_interpolator_ccf",
+ gr.io_signature(1, 1, gr.sizeof_gr_complex),
+ gr.io_signature(1, 1, gr.sizeof_gr_complex))
+
+ self._interp = interp
+ self._taps = taps
+
+ if taps is not None:
+ self._taps = taps
+ else:
+ # Create a filter that covers the full bandwidth of the input signal
+ bw = 0.4
+ tb = 0.2
+ ripple = 0.99
+ made = False
+ while not made:
+ try:
+ self._taps = optfir.low_pass(self._interp, self._interp, bw, bw+tb, ripple, atten)
+ made = True
+ except RuntimeError:
+ ripple += 0.01
+ made = False
+ print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple))
+
+ # Build in an exit strategy; if we've come this far, it ain't working.
+ if(ripple >= 1.0):
+ raise RuntimeError("optfir could not generate an appropriate filter.")
+
+ self.pfb = filter.pfb_interpolator_ccf(self._interp, self._taps)
+
+ self.connect(self, self.pfb)
+ self.connect(self.pfb, self)
+
+
+class decimator_ccf(gr.hier_block2):
+ '''
+ Make a Polyphase Filter decimator (complex in, complex out, floating-point taps)
+
+ This simplifies the interface by allowing a single input stream to connect to this block.
+ It will then output a stream that is the decimated output stream.
+ '''
+ def __init__(self, decim, taps=None, channel=0, atten=100):
+ gr.hier_block2.__init__(self, "pfb_decimator_ccf",
+ gr.io_signature(1, 1, gr.sizeof_gr_complex),
+ gr.io_signature(1, 1, gr.sizeof_gr_complex))
+
+ self._decim = decim
+ self._channel = channel
+
+ if taps is not None:
+ self._taps = taps
+ else:
+ # Create a filter that covers the full bandwidth of the input signal
+ bw = 0.4
+ tb = 0.2
+ ripple = 0.1
+ made = False
+ while not made:
+ try:
+ self._taps = optfir.low_pass(1, self._decim, bw, bw+tb, ripple, atten)
+ made = True
+ except RuntimeError:
+ ripple += 0.01
+ made = False
+ print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple))
+
+ # Build in an exit strategy; if we've come this far, it ain't working.
+ if(ripple >= 1.0):
+ raise RuntimeError("optfir could not generate an appropriate filter.")
+
+ self.s2ss = gr.stream_to_streams(gr.sizeof_gr_complex, self._decim)
+ self.pfb = filter.pfb_decimator_ccf(self._decim, self._taps, self._channel)
+
+ self.connect(self, self.s2ss)
+
+ for i in xrange(self._decim):
+ self.connect((self.s2ss,i), (self.pfb,i))
+
+ self.connect(self.pfb, self)
+
+
+class arb_resampler_ccf(gr.hier_block2):
+ '''
+ Convenience wrapper for the polyphase filterbank arbitrary resampler.
+
+ The block takes a single complex stream in and outputs a single complex
+ stream out. As such, it requires no extra glue to handle the input/output
+ streams. This block is provided to be consistent with the interface to the
+ other PFB block.
+ '''
+ def __init__(self, rate, taps=None, flt_size=32, atten=100):
+ gr.hier_block2.__init__(self, "pfb_arb_resampler_ccf",
+ gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+ gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
+
+ self._rate = rate
+ self._size = flt_size
+
+ if taps is not None:
+ self._taps = taps
+ else:
+ # Create a filter that covers the full bandwidth of the input signal
+ bw = 0.4
+ tb = 0.2
+ ripple = 0.1
+ #self._taps = filter.firdes.low_pass_2(self._size, self._size, bw, tb, atten)
+ made = False
+ while not made:
+ try:
+ self._taps = optfir.low_pass(self._size, self._size, bw, bw+tb, ripple, atten)
+ made = True
+ except RuntimeError:
+ ripple += 0.01
+ made = False
+ print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple))
+
+ # Build in an exit strategy; if we've come this far, it ain't working.
+ if(ripple >= 1.0):
+ raise RuntimeError("optfir could not generate an appropriate filter.")
+
+ self.pfb = filter.pfb_arb_resampler_ccf(self._rate, self._taps, self._size)
+ #print "PFB has %d taps\n" % (len(self._taps),)
+
+ self.connect(self, self.pfb)
+ self.connect(self.pfb, self)
+
+ # Note -- set_taps not implemented in base class yet
+ def set_taps(self, taps):
+ self.pfb.set_taps(taps)
+
+ def set_rate(self, rate):
+ self.pfb.set_rate(rate)
+
+
+class arb_resampler_fff(gr.hier_block2):
+ '''
+ Convenience wrapper for the polyphase filterbank arbitrary resampler.
+
+ The block takes a single float stream in and outputs a single float
+ stream out. As such, it requires no extra glue to handle the input/output
+ streams. This block is provided to be consistent with the interface to the
+ other PFB block.
+ '''
+ def __init__(self, rate, taps=None, flt_size=32, atten=100):
+ gr.hier_block2.__init__(self, "pfb_arb_resampler_fff",
+ gr.io_signature(1, 1, gr.sizeof_float), # Input signature
+ gr.io_signature(1, 1, gr.sizeof_float)) # Output signature
+
+ self._rate = rate
+ self._size = flt_size
+
+ if taps is not None:
+ self._taps = taps
+ else:
+ # Create a filter that covers the full bandwidth of the input signal
+ bw = 0.4
+ tb = 0.2
+ ripple = 0.1
+ #self._taps = filter.firdes.low_pass_2(self._size, self._size, bw, tb, atten)
+ made = False
+ while not made:
+ try:
+ self._taps = optfir.low_pass(self._size, self._size, bw, bw+tb, ripple, atten)
+ made = True
+ except RuntimeError:
+ ripple += 0.01
+ made = False
+ print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple))
+
+ # Build in an exit strategy; if we've come this far, it ain't working.
+ if(ripple >= 1.0):
+ raise RuntimeError("optfir could not generate an appropriate filter.")
+
+ self.pfb = filter.pfb_arb_resampler_fff(self._rate, self._taps, self._size)
+ #print "PFB has %d taps\n" % (len(self._taps),)
+
+ self.connect(self, self.pfb)
+ self.connect(self.pfb, self)
+
+ # Note -- set_taps not implemented in base class yet
+ def set_taps(self, taps):
+ self.pfb.set_taps(taps)
+
+ def set_rate(self, rate):
+ self.pfb.set_rate(rate)
diff --git a/gr-filter/python/qa_adaptive_fir_filter.py b/gr-filter/python/qa_adaptive_fir_filter.py
new file mode 100755
index 0000000000..cadce52044
--- /dev/null
+++ b/gr-filter/python/qa_adaptive_fir_filter.py
@@ -0,0 +1,159 @@
+#!/usr/bin/env python
+#
+# Copyright 2008,2010,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+from gnuradio import gr, gr_unittest
+import filter_swig as filter
+
+class test_adaptive_filter(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block ()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_adaptive_fir_filter_ccf_001(self):
+ src_data = 40*[1+1j, 2+2j, 3+3j, 4+4j]
+ expected_data = ((0.5+0.5j), (1.5+1.5j), (3+3j), (5+5j), (5.5+5.5j),
+ (6.5+6.5j), (8+8j), (10+10j), (10.5+10.5j), (11.5+11.5j),
+ (13+13j), (15+15j), (15.5+15.5j), (16.5+16.5j), (18+18j),
+ (20+20j), (20.5+20.5j), (21.5+21.5j), (23+23j), (25+25j),
+ (25.5+25.5j), (26.5+26.5j), (28+28j), (30+30j), (30.5+30.5j),
+ (31.5+31.5j), (33+33j), (35+35j), (35.5+35.5j), (36.5+36.5j),
+ (38+38j), (40+40j), (40.5+40.5j), (41.5+41.5j), (43+43j),
+ (45+45j), (45.5+45.5j), (46.5+46.5j), (48+48j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j))
+
+ src = gr.vector_source_c(src_data)
+ op = filter.adaptive_fir_ccf("test", 1, 20*[0.5, 0.5])
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5)
+
+ def test_adaptive_fir_filter_ccf_002(self):
+ src_data = 40*[1+1j, 2+2j, 3+3j, 4+4j]
+ expected_data = ((0.5+0.5j), (5.5+5.5j), (10.5+10.5j), (15.5+15.5j),
+ (20.5+20.5j), (25.5+25.5j), (30.5+30.5j), (35.5+35.5j),
+ (40.5+40.5j), (45.5+45.5j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j))
+
+ src = gr.vector_source_c(src_data)
+ op = filter.adaptive_fir_ccf("test", 4, 20*[0.5, 0.5])
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5)
+
+ def test_adaptive_fir_filter_ccc_001(self):
+ src_data = 40*[1+1j, 2+2j, 3+3j, 4+4j]
+ expected_data = ((-0.5+1.5j), (-1.5+4.5j), (-3+9j), (-5+15j),
+ (-5.5+16.5j), (-6.5+19.5j), (-8+24j), (-10+30j),
+ (-10.5+31.5j), (-11.5+34.5j), (-13+39j), (-15+45j),
+ (-15.5+46.5j), (-16.5+49.5j), (-18+54j), (-20+60j),
+ (-20.5+61.5j), (-21.5+64.5j), (-23+69j), (-25+75j),
+ (-25.5+76.5j), (-26.5+79.5j), (-28+84j), (-30+90j),
+ (-30.5+91.5j), (-31.5+94.5j), (-33+99j), (-35+105j),
+ (-35.5+106.5j), (-36.5+109.5j), (-38+114j), (-40+120j),
+ (-40.5+121.5j), (-41.5+124.5j), (-43+129j), (-45+135j),
+ (-45.5+136.5j), (-46.5+139.5j), (-48+144j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j))
+ src = gr.vector_source_c(src_data)
+ op = filter.adaptive_fir_ccc("test", 1, 20*[0.5+1j, 0.5+1j])
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5)
+
+
+ def test_adaptive_fir_filter_ccc_002(self):
+ src_data = 40*[1+1j, 2+2j, 3+3j, 4+4j]
+ expected_data = ((-0.5+1.5j), (-5.5+16.5j), (-10.5+31.5j),
+ (-15.5+46.5j), (-20.5+61.5j), (-25.5+76.5j),
+ (-30.5+91.5j), (-35.5+106.5j), (-40.5+121.5j),
+ (-45.5+136.5j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j))
+ src = gr.vector_source_c(src_data)
+ op = filter.adaptive_fir_ccc("test", 4, 20*[0.5+1j, 0.5+1j])
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_adaptive_filter, "test_adaptive_filter.xml")
+
diff --git a/gr-filter/python/qa_channel_model.py b/gr-filter/python/qa_channel_model.py
new file mode 100755
index 0000000000..7f1c61b4e3
--- /dev/null
+++ b/gr-filter/python/qa_channel_model.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import filter_swig as filter
+import math
+
+class test_channel_model(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_000(self):
+ N = 1000 # number of samples to use
+ fs = 1000 # baseband sampling rate
+ freq = 100
+
+ signal = gr.sig_source_c(fs, gr.GR_SIN_WAVE, freq, 1)
+ head = gr.head(gr.sizeof_gr_complex, N)
+ op = filter.channel_model(0.0, 0.0, 1.0, [1,], 0)
+ snk = gr.vector_sink_c()
+ snk1 = gr.vector_sink_c()
+
+ op.set_noise_voltage(0.0)
+ op.set_frequency_offset(0.0)
+ op.set_taps([1,])
+ op.set_timing_offset(1.0)
+
+ self.tb.connect(signal, head, op, snk)
+ self.tb.connect(op, snk1)
+ self.tb.run()
+
+ dst_data = snk.data()
+ exp_data = snk1.data()
+ self.assertComplexTuplesAlmostEqual(exp_data, dst_data, 5)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_channel_model, "test_channel_model.xml")
diff --git a/gr-filter/python/qa_dc_blocker.py b/gr-filter/python/qa_dc_blocker.py
new file mode 100755
index 0000000000..b9df06b453
--- /dev/null
+++ b/gr-filter/python/qa_dc_blocker.py
@@ -0,0 +1,109 @@
+#!/usr/bin/env python
+#
+# Copyright 2011,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import filter_swig as filter
+
+class test_dc_blocker(gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_001(self):
+ ''' Test impulse response - long form, cc '''
+ src_data = [1,] + 100*[0,]
+ expected_result = ((-0.02072429656982422+0j), (-0.02081298828125+0j),
+ (0.979156494140625+0j), (-0.02081298828125+0j),
+ (-0.02072429656982422+0j))
+
+ src = gr.vector_source_c(src_data)
+ op = filter.dc_blocker_cc(32, True)
+ dst = gr.vector_sink_c()
+
+ self.tb.connect (src, op, dst)
+ self.tb.run()
+
+ # only test samples around 2D-2
+ result_data = dst.data()[60:65]
+ self.assertComplexTuplesAlmostEqual (expected_result, result_data)
+
+ def test_002(self):
+ ''' Test impulse response - short form, cc '''
+ src_data = [1,] + 100*[0,]
+ expected_result = ((-0.029296875+0j), (-0.0302734375+0j),
+ (0.96875+0j), (-0.0302734375+0j),
+ (-0.029296875+0j))
+
+ src = gr.vector_source_c(src_data)
+ op = filter.dc_blocker_cc(32, False)
+ dst = gr.vector_sink_c()
+
+ self.tb.connect (src, op, dst)
+ self.tb.run()
+
+ # only test samples around D-1
+ result_data = dst.data()[29:34]
+ self.assertComplexTuplesAlmostEqual (expected_result, result_data)
+
+
+ def test_003(self):
+ ''' Test impulse response - long form, ff '''
+ src_data = [1,] + 100*[0,]
+ expected_result = ((-0.02072429656982422), (-0.02081298828125),
+ (0.979156494140625), (-0.02081298828125),
+ (-0.02072429656982422))
+
+ src = gr.vector_source_f(src_data)
+ op = filter.dc_blocker_ff(32, True)
+ dst = gr.vector_sink_f()
+
+ self.tb.connect (src, op, dst)
+ self.tb.run()
+
+ # only test samples around 2D-2
+ result_data = dst.data()[60:65]
+ self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+
+ def test_004(self):
+ ''' Test impulse response - short form, ff '''
+ src_data = [1,] + 100*[0,]
+ expected_result = ((-0.029296875), (-0.0302734375),
+ (0.96875), (-0.0302734375),
+ (-0.029296875))
+
+ src = gr.vector_source_f(src_data)
+ op = filter.dc_blocker_ff(32, False)
+ dst = gr.vector_sink_f()
+
+ self.tb.connect (src, op, dst)
+ self.tb.run()
+
+ # only test samples around D-1
+ result_data = dst.data()[29:34]
+ self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_dc_blocker, "test_dc_blocker.xml")
+
diff --git a/gr-filter/python/qa_fft_filter.py b/gr-filter/python/qa_fft_filter.py
new file mode 100755
index 0000000000..cb5416373f
--- /dev/null
+++ b/gr-filter/python/qa_fft_filter.py
@@ -0,0 +1,380 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2005,2007,2010,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import filter_swig as filter
+import sys
+import random
+
+def make_random_complex_tuple(L):
+ result = []
+ for x in range(L):
+ result.append(complex(2*random.random()-1,
+ 2*random.random()-1))
+ return tuple(result)
+
+def make_random_float_tuple(L):
+ result = []
+ for x in range(L):
+ result.append(float(int(2*random.random()-1)))
+ return tuple(result)
+
+
+def reference_filter_ccc(dec, taps, input):
+ """
+ compute result using conventional fir filter
+ """
+ tb = gr.top_block()
+ #src = gr.vector_source_c(((0,) * (len(taps) - 1)) + input)
+ src = gr.vector_source_c(input)
+ op = filter.fir_filter_ccc(dec, taps)
+ dst = gr.vector_sink_c()
+ tb.connect(src, op, dst)
+ tb.run()
+ return dst.data()
+
+def reference_filter_fff(dec, taps, input):
+ """
+ compute result using conventional fir filter
+ """
+ tb = gr.top_block()
+ #src = gr.vector_source_f(((0,) * (len(taps) - 1)) + input)
+ src = gr.vector_source_f(input)
+ op = filter.fir_filter_fff(dec, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op, dst)
+ tb.run()
+ return dst.data()
+
+
+def print_complex(x):
+ for i in x:
+ i = complex(i)
+ sys.stdout.write("(%6.3f,%6.3fj), " % (i.real, i.imag))
+ sys.stdout.write('\n')
+
+
+class test_fft_filter(gr_unittest.TestCase):
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def assert_fft_ok2(self, expected_result, result_data):
+ expected_result = expected_result[:len(result_data)]
+ self.assertComplexTuplesAlmostEqual2 (expected_result, result_data,
+ abs_eps=1e-9, rel_eps=4e-4)
+
+ def assert_fft_float_ok2(self, expected_result, result_data, abs_eps=1e-9, rel_eps=4e-4):
+ expected_result = expected_result[:len(result_data)]
+ self.assertFloatTuplesAlmostEqual2 (expected_result, result_data,
+ abs_eps, rel_eps)
+
+ def test_ccc_001(self):
+ tb = gr.top_block()
+ src_data = (0,1,2,3,4,5,6,7)
+ taps = (1,)
+ expected_result = tuple([complex(x) for x in (0,1,2,3,4,5,6,7)])
+ src = gr.vector_source_c(src_data)
+ op = filter.fft_filter_ccc(1, taps)
+ dst = gr.vector_sink_c()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+ #print 'expected:', expected_result
+ #print 'results: ', result_data
+ self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5)
+
+
+ def test_ccc_002(self):
+ # Test nthreads
+ tb = gr.top_block()
+ src_data = (0,1,2,3,4,5,6,7)
+ taps = (2,)
+ nthreads = 2
+ expected_result = tuple([2 * complex(x) for x in (0,1,2,3,4,5,6,7)])
+ src = gr.vector_source_c(src_data)
+ op = filter.fft_filter_ccc(1, taps, nthreads)
+ dst = gr.vector_sink_c()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+ #print 'expected:', expected_result
+ #print 'results: ', result_data
+ self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5)
+
+ def test_ccc_003(self):
+ tb = gr.top_block()
+ src_data = (0,1,2,3,4,5,6,7)
+ taps = (2,)
+ expected_result = tuple([2 * complex(x) for x in (0,1,2,3,4,5,6,7)])
+ src = gr.vector_source_c(src_data)
+ op = filter.fft_filter_ccc(1, taps)
+ dst = gr.vector_sink_c()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+ #print 'expected:', expected_result
+ #print 'results: ', result_data
+ self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5)
+
+
+ def test_ccc_004(self):
+ random.seed(0)
+ for i in xrange(25):
+ # sys.stderr.write("\n>>> Loop = %d\n" % (i,))
+ src_len = 4*1024
+ src_data = make_random_complex_tuple(src_len)
+ ntaps = int(random.uniform(2, 1000))
+ taps = make_random_complex_tuple(ntaps)
+ expected_result = reference_filter_ccc(1, taps, src_data)
+
+ src = gr.vector_source_c(src_data)
+ op = filter.fft_filter_ccc(1, taps)
+ dst = gr.vector_sink_c()
+ tb = gr.top_block()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+ del tb
+ self.assert_fft_ok2(expected_result, result_data)
+
+ def test_ccc_005(self):
+ random.seed(0)
+ for i in xrange(25):
+ # sys.stderr.write("\n>>> Loop = %d\n" % (i,))
+ dec = i + 1
+ src_len = 4*1024
+ src_data = make_random_complex_tuple(src_len)
+ ntaps = int(random.uniform(2, 100))
+ taps = make_random_complex_tuple(ntaps)
+ expected_result = reference_filter_ccc(dec, taps, src_data)
+
+ src = gr.vector_source_c(src_data)
+ op = filter.fft_filter_ccc(dec, taps)
+ dst = gr.vector_sink_c()
+ tb = gr.top_block()
+ tb.connect(src, op, dst)
+ tb.run()
+ del tb
+ result_data = dst.data()
+
+ self.assert_fft_ok2(expected_result, result_data)
+
+ def test_ccc_006(self):
+ # Test decimating with nthreads=2
+ random.seed(0)
+ nthreads = 2
+ for i in xrange(25):
+ # sys.stderr.write("\n>>> Loop = %d\n" % (i,))
+ dec = i + 1
+ src_len = 4*1024
+ src_data = make_random_complex_tuple(src_len)
+ ntaps = int(random.uniform(2, 100))
+ taps = make_random_complex_tuple(ntaps)
+ expected_result = reference_filter_ccc(dec, taps, src_data)
+
+ src = gr.vector_source_c(src_data)
+ op = filter.fft_filter_ccc(dec, taps, nthreads)
+ dst = gr.vector_sink_c()
+ tb = gr.top_block()
+ tb.connect(src, op, dst)
+ tb.run()
+ del tb
+ result_data = dst.data()
+
+ self.assert_fft_ok2(expected_result, result_data)
+
+ # ----------------------------------------------------------------
+ # test _fff version
+ # ----------------------------------------------------------------
+
+ def test_fff_001(self):
+ tb = gr.top_block()
+ src_data = (0,1,2,3,4,5,6,7)
+ taps = (1,)
+ expected_result = tuple([float(x) for x in (0,1,2,3,4,5,6,7)])
+ src = gr.vector_source_f(src_data)
+ op = filter.fft_filter_fff(1, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+ #print 'expected:', expected_result
+ #print 'results: ', result_data
+ self.assertFloatTuplesAlmostEqual (expected_result, result_data, 5)
+
+
+ def test_fff_002(self):
+ tb = gr.top_block()
+ src_data = (0,1,2,3,4,5,6,7)
+ taps = (2,)
+ expected_result = tuple([2 * float(x) for x in (0,1,2,3,4,5,6,7)])
+ src = gr.vector_source_f(src_data)
+ op = filter.fft_filter_fff(1, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+ #print 'expected:', expected_result
+ #print 'results: ', result_data
+ self.assertFloatTuplesAlmostEqual (expected_result, result_data, 5)
+
+ def test_fff_003(self):
+ # Test 02 with nthreads
+ tb = gr.top_block()
+ src_data = (0,1,2,3,4,5,6,7)
+ taps = (2,)
+ nthreads = 2
+ expected_result = tuple([2 * float(x) for x in (0,1,2,3,4,5,6,7)])
+ src = gr.vector_source_f(src_data)
+ op = filter.fft_filter_fff(1, taps, nthreads)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+ self.assertFloatTuplesAlmostEqual (expected_result, result_data, 5)
+
+ def xtest_fff_004(self):
+ random.seed(0)
+ for i in xrange(25):
+ sys.stderr.write("\n>>> Loop = %d\n" % (i,))
+ src_len = 4096
+ src_data = make_random_float_tuple(src_len)
+ ntaps = int(random.uniform(2, 1000))
+ taps = make_random_float_tuple(ntaps)
+ expected_result = reference_filter_fff(1, taps, src_data)
+
+ src = gr.vector_source_f(src_data)
+ op = filter.fft_filter_fff(1, taps)
+ dst = gr.vector_sink_f()
+ tb = gr.top_block()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+
+ #print "src_len =", src_len, " ntaps =", ntaps
+ try:
+ self.assert_fft_float_ok2(expected_result, result_data, abs_eps=1.0)
+ except:
+ expected = open('expected', 'w')
+ for x in expected_result:
+ expected.write(`x` + '\n')
+ actual = open('actual', 'w')
+ for x in result_data:
+ actual.write(`x` + '\n')
+ raise
+
+ def xtest_fff_005(self):
+ random.seed(0)
+ for i in xrange(25):
+ sys.stderr.write("\n>>> Loop = %d\n" % (i,))
+ src_len = 4*1024
+ src_data = make_random_float_tuple(src_len)
+ ntaps = int(random.uniform(2, 1000))
+ taps = make_random_float_tuple(ntaps)
+ expected_result = reference_filter_fff(1, taps, src_data)
+
+ src = gr.vector_source_f(src_data)
+ op = filter.fft_filter_fff(1, taps)
+ dst = gr.vector_sink_f()
+ tb = gr.top_block()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+
+ self.assert_fft_float_ok2(expected_result, result_data, abs_eps=2.0)
+
+ def xtest_fff_006(self):
+ random.seed(0)
+ for i in xrange(25):
+ sys.stderr.write("\n>>> Loop = %d\n" % (i,))
+ dec = i + 1
+ src_len = 4*1024
+ src_data = make_random_float_tuple(src_len)
+ ntaps = int(random.uniform(2, 100))
+ taps = make_random_float_tuple(ntaps)
+ expected_result = reference_filter_fff(dec, taps, src_data)
+
+ src = gr.vector_source_f(src_data)
+ op = filter.fft_filter_fff(dec, taps)
+ dst = gr.vector_sink_f()
+ tb = gr.top_block()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+
+ self.assert_fft_float_ok2(expected_result, result_data)
+
+ def xtest_fff_007(self):
+ # test decimation with nthreads
+ random.seed(0)
+ nthreads = 2
+ for i in xrange(25):
+ sys.stderr.write("\n>>> Loop = %d\n" % (i,))
+ dec = i + 1
+ src_len = 4*1024
+ src_data = make_random_float_tuple(src_len)
+ ntaps = int(random.uniform(2, 100))
+ taps = make_random_float_tuple(ntaps)
+ expected_result = reference_filter_fff(dec, taps, src_data)
+
+ src = gr.vector_source_f(src_data)
+ op = filter.fft_filter_fff(dec, taps, nthreads)
+ dst = gr.vector_sink_f()
+ tb = gr.top_block()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+
+ self.assert_fft_float_ok2(expected_result, result_data)
+
+ def test_fff_get0(self):
+ random.seed(0)
+ for i in xrange(25):
+ ntaps = int(random.uniform(2, 100))
+ taps = make_random_float_tuple(ntaps)
+
+ op = filter.fft_filter_fff(1, taps)
+ result_data = op.taps()
+ #print result_data
+
+ self.assertEqual(taps, result_data)
+
+ def test_ccc_get0(self):
+ random.seed(0)
+ for i in xrange(25):
+ ntaps = int(random.uniform(2, 100))
+ taps = make_random_complex_tuple(ntaps)
+
+ op = filter.fft_filter_ccc(1, taps)
+ result_data = op.taps()
+ #print result_data
+
+ self.assertComplexTuplesAlmostEqual(taps, result_data, 4)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_fft_filter, "test_fft_filter.xml")
+
diff --git a/gr-filter/python/qa_filter_delay_fc.py b/gr-filter/python/qa_filter_delay_fc.py
new file mode 100755
index 0000000000..57b063e7b5
--- /dev/null
+++ b/gr-filter/python/qa_filter_delay_fc.py
@@ -0,0 +1,318 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import filter_swig as filter
+import math
+
+class test_filter_delay_fc(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_001_filter_delay_one_input(self):
+
+ # expected result
+ expected_result = ( -1.4678005338941702e-11j,
+ -0.0011950774351134896j,
+ -0.0019336787518113852j,
+ -0.0034673355985432863j,
+ -0.0036765895783901215j,
+ -0.004916108213365078j,
+ -0.0042778430506587029j,
+ -0.006028641015291214j,
+ -0.005476709920912981j,
+ -0.0092810001224279404j,
+ -0.0095402700826525688j,
+ -0.016060983762145042j,
+ -0.016446959227323532j,
+ -0.02523401565849781j,
+ -0.024382550269365311j,
+ -0.035477779805660248j,
+ -0.033021725714206696j,
+ -0.048487484455108643j,
+ -0.04543270543217659j,
+ -0.069477587938308716j,
+ -0.066984444856643677j,
+ -0.10703597217798233j,
+ -0.10620346665382385j,
+ -0.1852707713842392j,
+ -0.19357112050056458j,
+ (7.2191945754696007e-09 -0.50004088878631592j),
+ (0.58778399229049683 -0.6155126690864563j),
+ (0.95105588436126709 -0.12377222627401352j),
+ (0.95105588436126709 +0.41524654626846313j),
+ (0.5877838134765625 +0.91611981391906738j),
+ (5.8516356205018383e-09 +1.0670661926269531j),
+ (-0.5877840518951416 +0.87856143712997437j),
+ (-0.95105588436126709 +0.35447561740875244j),
+ (-0.95105588436126709 -0.26055556535720825j),
+ (-0.5877838134765625 -0.77606213092803955j),
+ (-8.7774534307527574e-09 -0.96460390090942383j),
+ (0.58778399229049683 -0.78470128774642944j),
+ (0.95105588436126709 -0.28380891680717468j),
+ (0.95105588436126709 +0.32548999786376953j),
+ (0.5877838134765625 +0.82514488697052002j),
+ (1.4629089051254596e-08 +1.0096219778060913j),
+ (-0.5877840518951416 +0.81836479902267456j),
+ (-0.95105588436126709 +0.31451958417892456j),
+ (-0.95105588436126709 -0.3030143678188324j),
+ (-0.5877838134765625 -0.80480599403381348j),
+ (-1.7554906861505515e-08 -0.99516552686691284j),
+ (0.58778399229049683 -0.80540722608566284j),
+ (0.95105582475662231 -0.30557557940483093j),
+ (0.95105588436126709 +0.31097668409347534j),
+ (0.5877838134765625 +0.81027895212173462j),
+ (2.3406542482007353e-08 +1.0000816583633423j),
+ (-0.5877840518951416 +0.80908381938934326j),
+ (-0.95105588436126709 +0.30904293060302734j),
+ (-0.95105588436126709 -0.30904296040534973j),
+ (-0.5877838134765625 -0.80908387899398804j),
+ (-2.6332360292258272e-08 -1.0000815391540527j),
+ (0.58778399229049683 -0.80908381938934326j),
+ (0.95105582475662231 -0.30904299020767212j),
+ (0.95105588436126709 +0.30904293060302734j),
+ (0.5877838134765625 +0.80908381938934326j),
+ (3.218399768911695e-08 +1.0000815391540527j))
+
+ tb = self.tb
+
+ sampling_freq = 100
+
+ ntaps = 51
+ src1 = gr.sig_source_f(sampling_freq, gr.GR_SIN_WAVE,
+ sampling_freq * 0.10, 1.0)
+ head = gr.head(gr.sizeof_float, int(ntaps + sampling_freq * 0.10))
+ dst2 = gr.vector_sink_c()
+
+ # calculate taps
+ taps = filter.firdes_hilbert(ntaps)
+ hd = filter.filter_delay_fc(taps)
+
+ tb.connect(src1, head)
+ tb.connect(head, hd)
+ tb.connect(hd,dst2)
+
+ tb.run()
+
+ # get output
+ result_data = dst2.data()
+ self.assertComplexTuplesAlmostEqual(expected_result, result_data, 5)
+
+ def test_002_filter_delay_two_inputs(self):
+
+ # giving the same signal to both the inputs should fetch the same results
+ # as above
+
+ # expected result
+ expected_result = ( -1.4678005338941702e-11j,
+ -0.0011950774351134896j,
+ -0.0019336787518113852j,
+ -0.0034673355985432863j,
+ -0.0036765895783901215j,
+ -0.004916108213365078j,
+ -0.0042778430506587029j,
+ -0.006028641015291214j,
+ -0.005476709920912981j,
+ -0.0092810001224279404j,
+ -0.0095402700826525688j,
+ -0.016060983762145042j,
+ -0.016446959227323532j,
+ -0.02523401565849781j,
+ -0.024382550269365311j,
+ -0.035477779805660248j,
+ -0.033021725714206696j,
+ -0.048487484455108643j,
+ -0.04543270543217659j,
+ -0.069477587938308716j,
+ -0.066984444856643677j,
+ -0.10703597217798233j,
+ -0.10620346665382385j,
+ -0.1852707713842392j,
+ -0.19357112050056458j,
+ (7.2191945754696007e-09 -0.50004088878631592j),
+ (0.58778399229049683 -0.6155126690864563j),
+ (0.95105588436126709 -0.12377222627401352j),
+ (0.95105588436126709 +0.41524654626846313j),
+ (0.5877838134765625 +0.91611981391906738j),
+ (5.8516356205018383e-09 +1.0670661926269531j),
+ (-0.5877840518951416 +0.87856143712997437j),
+ (-0.95105588436126709 +0.35447561740875244j),
+ (-0.95105588436126709 -0.26055556535720825j),
+ (-0.5877838134765625 -0.77606213092803955j),
+ (-8.7774534307527574e-09 -0.96460390090942383j),
+ (0.58778399229049683 -0.78470128774642944j),
+ (0.95105588436126709 -0.28380891680717468j),
+ (0.95105588436126709 +0.32548999786376953j),
+ (0.5877838134765625 +0.82514488697052002j),
+ (1.4629089051254596e-08 +1.0096219778060913j),
+ (-0.5877840518951416 +0.81836479902267456j),
+ (-0.95105588436126709 +0.31451958417892456j),
+ (-0.95105588436126709 -0.3030143678188324j),
+ (-0.5877838134765625 -0.80480599403381348j),
+ (-1.7554906861505515e-08 -0.99516552686691284j),
+ (0.58778399229049683 -0.80540722608566284j),
+ (0.95105582475662231 -0.30557557940483093j),
+ (0.95105588436126709 +0.31097668409347534j),
+ (0.5877838134765625 +0.81027895212173462j),
+ (2.3406542482007353e-08 +1.0000816583633423j),
+ (-0.5877840518951416 +0.80908381938934326j),
+ (-0.95105588436126709 +0.30904293060302734j),
+ (-0.95105588436126709 -0.30904296040534973j),
+ (-0.5877838134765625 -0.80908387899398804j),
+ (-2.6332360292258272e-08 -1.0000815391540527j),
+ (0.58778399229049683 -0.80908381938934326j),
+ (0.95105582475662231 -0.30904299020767212j),
+ (0.95105588436126709 +0.30904293060302734j),
+ (0.5877838134765625 +0.80908381938934326j),
+ (3.218399768911695e-08 +1.0000815391540527j))
+
+
+ tb = self.tb
+
+ sampling_freq = 100
+ ntaps = 51
+ src1 = gr.sig_source_f(sampling_freq, gr.GR_SIN_WAVE,
+ sampling_freq * 0.10, 1.0)
+ head = gr.head(gr.sizeof_float, int(ntaps + sampling_freq * 0.10))
+ dst2 = gr.vector_sink_c()
+
+
+ # calculate taps
+ taps = filter.firdes_hilbert(ntaps)
+ hd = filter.filter_delay_fc(taps)
+
+ tb.connect(src1, head)
+ tb.connect(head, (hd,0))
+ tb.connect(head, (hd,1))
+ tb.connect(hd,dst2)
+ tb.run()
+
+ # get output
+ result_data = dst2.data()
+
+ self.assertComplexTuplesAlmostEqual(expected_result, result_data, 5)
+
+
+ def test_003_filter_delay_two_inputs(self):
+
+ # give two different inputs
+
+ # expected result
+ expected_result = ( -0.0020331963896751404j,
+ -0.0016448829555884004j,
+ -0.0032375147566199303j,
+ -0.0014826074475422502j,
+ -0.0033034090884029865j,
+ -0.00051144487224519253j,
+ -0.0043686260469257832j,
+ -0.0010198024101555347j,
+ -0.0082517862319946289j,
+ -0.003456643782556057j,
+ -0.014193611219525337j,
+ -0.005875137634575367j,
+ -0.020293503999710083j,
+ -0.0067503536120057106j,
+ -0.026798896491527557j,
+ -0.0073488112539052963j,
+ -0.037041611969470978j,
+ -0.010557252913713455j,
+ -0.055669989436864853j,
+ -0.018332764506340027j,
+ -0.089904911816120148j,
+ -0.033361352980136871j,
+ -0.16902604699134827j,
+ -0.074318811297416687j,
+ -0.58429563045501709j,
+ (7.2191945754696007e-09 -0.35892376303672791j),
+ (0.58778399229049683 +0.63660913705825806j),
+ (0.95105588436126709 +0.87681591510772705j),
+ (0.95105588436126709 +0.98705857992172241j),
+ (0.5877838134765625 +0.55447429418563843j),
+ (5.8516356205018383e-09 +0.026006083935499191j),
+ (-0.5877840518951416 -0.60616838932037354j),
+ (-0.95105588436126709 -0.9311758279800415j),
+ (-0.95105588436126709 -0.96169203519821167j),
+ (-0.5877838134765625 -0.57292771339416504j),
+ (-8.7774534307527574e-09 -0.0073488391935825348j),
+ (0.58778399229049683 +0.59720659255981445j),
+ (0.95105588436126709 +0.94438445568084717j),
+ (0.95105588436126709 +0.95582199096679688j),
+ (0.5877838134765625 +0.58196049928665161j),
+ (1.4629089051254596e-08 +0.0026587247848510742j),
+ (-0.5877840518951416 -0.59129220247268677j),
+ (-0.95105588436126709 -0.94841635227203369j),
+ (-0.95105588436126709 -0.95215457677841187j),
+ (-0.5877838134765625 -0.58535969257354736j),
+ (-1.7554906861505515e-08 -0.00051158666610717773j),
+ (0.58778399229049683 +0.58867418766021729j),
+ (0.95105582475662231 +0.94965213537216187j),
+ (0.95105588436126709 +0.95050644874572754j),
+ (0.5877838134765625 +0.58619076013565063j),
+ (2.3406542482007353e-08 +1.1920928955078125e-07j),
+ (-0.5877840518951416 -0.58783555030822754j),
+ (-0.95105588436126709 -0.95113480091094971j),
+ (-0.95105588436126709 -0.95113474130630493j),
+ (-0.5877838134765625 -0.58783555030822754j),
+ (-2.6332360292258272e-08 -8.1956386566162109e-08j),
+ (0.58778399229049683 +0.58783555030822754j),
+ (0.95105582475662231 +0.95113474130630493j),
+ (0.95105588436126709 +0.95113474130630493j),
+ (0.5877838134765625 +0.58783560991287231j),
+ (3.218399768911695e-08 +1.1920928955078125e-07j))
+
+ tb = self.tb
+
+ sampling_freq = 100
+ ntaps = 51
+
+ src1 = gr.sig_source_f(sampling_freq, gr.GR_SIN_WAVE,sampling_freq * 0.10, 1.0)
+ src2 = gr.sig_source_f(sampling_freq, gr.GR_COS_WAVE,sampling_freq * 0.10, 1.0)
+
+ head1 = gr.head(gr.sizeof_float, int(ntaps + sampling_freq * 0.10))
+ head2 = gr.head(gr.sizeof_float, int(ntaps + sampling_freq * 0.10))
+
+ taps = filter.firdes_hilbert(ntaps)
+ hd = filter.filter_delay_fc(taps)
+
+ dst2 = gr.vector_sink_c()
+
+ tb.connect(src1, head1)
+ tb.connect(src2, head2)
+
+ tb.connect(head1, (hd,0))
+ tb.connect(head2, (hd,1))
+ tb.connect(hd, dst2)
+
+ tb.run()
+
+ # get output
+ result_data = dst2.data()
+
+ self.assertComplexTuplesAlmostEqual(expected_result, result_data, 5)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_filter_delay_fc, "test_filter_delay_fc.xml")
diff --git a/gr-filter/python/qa_fir_filter.py b/gr-filter/python/qa_fir_filter.py
new file mode 100755
index 0000000000..2a61498a26
--- /dev/null
+++ b/gr-filter/python/qa_fir_filter.py
@@ -0,0 +1,318 @@
+#!/usr/bin/env python
+#
+# Copyright 2008,2010,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+from gnuradio import gr, gr_unittest
+import filter_swig as filter
+
+class test_filter(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block ()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_fir_filter_fff_001(self):
+ src_data = 40*[1, 2, 3, 4]
+ expected_data = (0.5, 1.5, 3.0, 5.0, 5.5, 6.5, 8.0, 10.0,
+ 10.5, 11.5, 13.0, 15.0, 15.5, 16.5, 18.0,
+ 20.0, 20.5, 21.5, 23.0, 25.0, 25.5, 26.5,
+ 28.0, 30.0, 30.5, 31.5, 33.0, 35.0, 35.5,
+ 36.5, 38.0, 40.0, 40.5, 41.5, 43.0, 45.0,
+ 45.5, 46.5, 48.0, 50.0, 50.0, 50.0, 50.0,
+ 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0,
+ 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0,
+ 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0,
+ 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0,
+ 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0,
+ 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0,
+ 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0,
+ 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0,
+ 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0,
+ 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0,
+ 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0,
+ 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0,
+ 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0,
+ 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0,
+ 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0,
+ 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0,
+ 50.0, 50.0, 50.0, 50.0, 50.0)
+ src = gr.vector_source_f(src_data)
+ op = filter.fir_filter_fff(1, 20*[0.5, 0.5])
+ dst = gr.vector_sink_f()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertFloatTuplesAlmostEqual(expected_data, result_data, 5)
+
+ def test_fir_filter_fff_002(self):
+ src_data = 40*[1, 2, 3, 4]
+ expected_data = (0.5, 5.5, 10.5, 15.5, 20.5, 25.5, 30.5, 35.5,
+ 40.5, 45.5, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0,
+ 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0,
+ 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0,
+ 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0)
+ src = gr.vector_source_f(src_data)
+ op = filter.fir_filter_fff(4, 20*[0.5, 0.5])
+ dst = gr.vector_sink_f()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertFloatTuplesAlmostEqual(expected_data, result_data, 5)
+
+ def test_fir_filter_ccf_001(self):
+ src_data = 40*[1+1j, 2+2j, 3+3j, 4+4j]
+ expected_data = ((0.5+0.5j), (1.5+1.5j), (3+3j), (5+5j), (5.5+5.5j),
+ (6.5+6.5j), (8+8j), (10+10j), (10.5+10.5j), (11.5+11.5j),
+ (13+13j), (15+15j), (15.5+15.5j), (16.5+16.5j), (18+18j),
+ (20+20j), (20.5+20.5j), (21.5+21.5j), (23+23j), (25+25j),
+ (25.5+25.5j), (26.5+26.5j), (28+28j), (30+30j), (30.5+30.5j),
+ (31.5+31.5j), (33+33j), (35+35j), (35.5+35.5j), (36.5+36.5j),
+ (38+38j), (40+40j), (40.5+40.5j), (41.5+41.5j), (43+43j),
+ (45+45j), (45.5+45.5j), (46.5+46.5j), (48+48j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j))
+
+ src = gr.vector_source_c(src_data)
+ op = filter.fir_filter_ccf(1, 20*[0.5, 0.5])
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5)
+
+ def test_fir_filter_ccf_002(self):
+ src_data = 40*[1+1j, 2+2j, 3+3j, 4+4j]
+ expected_data = ((0.5+0.5j), (5.5+5.5j), (10.5+10.5j), (15.5+15.5j),
+ (20.5+20.5j), (25.5+25.5j), (30.5+30.5j), (35.5+35.5j),
+ (40.5+40.5j), (45.5+45.5j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j), (50+50j),
+ (50+50j), (50+50j), (50+50j), (50+50j))
+
+ src = gr.vector_source_c(src_data)
+ op = filter.fir_filter_ccf(4, 20*[0.5, 0.5])
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5)
+
+ def test_fir_filter_ccc_001(self):
+ src_data = 40*[1+1j, 2+2j, 3+3j, 4+4j]
+ expected_data = ((-0.5+1.5j), (-1.5+4.5j), (-3+9j), (-5+15j),
+ (-5.5+16.5j), (-6.5+19.5j), (-8+24j), (-10+30j),
+ (-10.5+31.5j), (-11.5+34.5j), (-13+39j), (-15+45j),
+ (-15.5+46.5j), (-16.5+49.5j), (-18+54j), (-20+60j),
+ (-20.5+61.5j), (-21.5+64.5j), (-23+69j), (-25+75j),
+ (-25.5+76.5j), (-26.5+79.5j), (-28+84j), (-30+90j),
+ (-30.5+91.5j), (-31.5+94.5j), (-33+99j), (-35+105j),
+ (-35.5+106.5j), (-36.5+109.5j), (-38+114j), (-40+120j),
+ (-40.5+121.5j), (-41.5+124.5j), (-43+129j), (-45+135j),
+ (-45.5+136.5j), (-46.5+139.5j), (-48+144j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j), (-50+150j))
+ src = gr.vector_source_c(src_data)
+ op = filter.fir_filter_ccc(1, 20*[0.5+1j, 0.5+1j])
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5)
+
+
+ def test_fir_filter_ccc_002(self):
+ src_data = 10*[1+1j, 2+2j, 3+3j, 4+4j]
+
+ # results derived from original gr.fir_filter_ccc
+ expected_data = ((7.537424837948042e-20+7.537424837948042e-20j), (9.131923434324563e-05+9.131923434324563e-05j), (0.0003317668742965907+0.0003317668742965907j), (0.0007230418268591166+0.0007230418268591166j), (0.0012087896466255188+0.0012087896466255188j), (0.0013292605290189385+0.0013292605290189385j), (0.001120875240303576+0.001120875240303576j), (0.000744672492146492+0.000744672492146492j), (0.000429437990533188+0.000429437990533188j), (2.283908543176949e-05+2.283908543176949e-05j), (-0.0002245186478830874-0.0002245186478830874j), (-0.0001157080550910905-0.0001157080550910905j), (0.00041409023106098175+0.00041409023106098175j), (0.0009017843985930085+0.0009017843985930085j), (0.0012520025484263897+0.0012520025484263897j), (0.0014116164529696107+0.0014116164529696107j), (0.001393353333696723+0.001393353333696723j), (0.000912194955162704+0.000912194955162704j), (0.00022649182938039303+0.00022649182938039303j), (-0.00031363096786662936-0.00031363096786662936j), (-0.0003966730728279799-0.0003966730728279799j), (-0.00023757052258588374-0.00023757052258588374j), (0.00021952332463115454+0.00021952332463115454j), (0.0009092430118471384+0.0009092430118471384j), (0.001662317430600524+0.001662317430600524j), (0.0019024648936465383+0.0019024648936465383j), (0.0015955769922584295+0.0015955769922584295j), (0.0009144138311967254+0.0009144138311967254j), (0.0001872836146503687+0.0001872836146503687j), (-0.000581968342885375-0.000581968342885375j), (-0.0009886166080832481-0.0009886166080832481j), (-0.0007480768254026771-0.0007480768254026771j), (0.00018211957649327815+0.00018211957649327815j), (0.0012042406015098095+0.0012042406015098095j), (0.0020200139842927456+0.0020200139842927456j), (0.0023816542234271765+0.0023816542234271765j), (0.002195809967815876+0.002195809967815876j), (0.0012113333214074373+0.0012113333214074373j), (-0.00014088614261709154-0.00014088614261709154j), (-0.0012574587017297745-0.0012574587017297745j))
+
+ taps = filter.firdes.low_pass(1, 1, 0.1, 0.01)
+ src = gr.vector_source_c(src_data)
+ op = filter.fir_filter_ccc(1, taps)
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5)
+
+ def test_fir_filter_ccc_003(self):
+ src_data = 40*[1+1j, 2+2j, 3+3j, 4+4j]
+ expected_data = ((-0.5+1.5j), (-5.5+16.5j), (-10.5+31.5j),
+ (-15.5+46.5j), (-20.5+61.5j), (-25.5+76.5j),
+ (-30.5+91.5j), (-35.5+106.5j), (-40.5+121.5j),
+ (-45.5+136.5j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j), (-50+150j),
+ (-50+150j), (-50+150j), (-50+150j))
+ src = gr.vector_source_c(src_data)
+ op = filter.fir_filter_ccc(4, 20*[0.5+1j, 0.5+1j])
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5)
+
+
+ def test_fir_filter_scc_001(self):
+ src_data = 40*[1, 2, 3, 4]
+ expected_data = ((0.5+1j), (1.5+3j), (3+6j), (5+10j), (5.5+11j),
+ (6.5+13j), (8+16j), (10+20j), (10.5+21j), (11.5+23j),
+ (13+26j), (15+30j), (15.5+31j), (16.5+33j), (18+36j),
+ (20+40j), (20.5+41j), (21.5+43j), (23+46j), (25+50j),
+ (25.5+51j), (26.5+53j), (28+56j), (30+60j), (30.5+61j),
+ (31.5+63j), (33+66j), (35+70j), (35.5+71j), (36.5+73j),
+ (38+76j), (40+80j), (40.5+81j), (41.5+83j), (43+86j),
+ (45+90j), (45.5+91j), (46.5+93j), (48+96j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j))
+ src = gr.vector_source_s(src_data)
+ op = filter.fir_filter_scc(1, 20*[0.5+1j, 0.5+1j])
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5)
+
+
+ def test_fir_filter_scc_002(self):
+ src_data = 40*[1, 2, 3, 4]
+ expected_data = ((0.5+1j), (5.5+11j), (10.5+21j), (15.5+31j), (20.5+41j),
+ (25.5+51j), (30.5+61j), (35.5+71j), (40.5+81j), (45.5+91j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j),
+ (50+100j), (50+100j), (50+100j), (50+100j), (50+100j))
+ src = gr.vector_source_s(src_data)
+ op = filter.fir_filter_scc(4, 20*[0.5+1j, 0.5+1j])
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5)
+
+ def test_fir_filter_fsf_001(self):
+ src_data = 40*[1, 2, 3, 4]
+ expected_data =(0, 1, 3, 5, 5, 6, 8, 10, 10, 11, 13, 15, 15, 16, 18, 20, 20,
+ 21, 23, 25, 25, 26, 28, 30, 30, 31, 33, 35, 35, 36, 38, 40, 40,
+ 41, 43, 45, 45, 46, 48, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50)
+ src = gr.vector_source_f(src_data)
+ op = filter.fir_filter_fsf(1, 20*[0.5, 0.5])
+ dst = gr.vector_sink_s()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5)
+
+
+ def test_fir_filter_fsf_002(self):
+ src_data = 40*[1, 2, 3, 4]
+ expected_data = (0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50)
+ src = gr.vector_source_f(src_data)
+ op = filter.fir_filter_fsf(4, 20*[0.5, 0.5])
+ dst = gr.vector_sink_s()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_filter, "test_filter.xml")
+
diff --git a/gr-filter/python/qa_firdes.py b/gr-filter/python/qa_firdes.py
new file mode 100755
index 0000000000..cfd10435f5
--- /dev/null
+++ b/gr-filter/python/qa_firdes.py
@@ -0,0 +1,202 @@
+#!/usr/bin/env python
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import filter_swig as filter
+import sys
+
+class test_firdes(gr_unittest.TestCase):
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_low_pass(self):
+ known_taps = (0.0030193300917744637, -0.004960992839187384,
+ 0.006678304169327021, -1.132049690556083e-17,
+ -0.0251916591078043, 0.07206480950117111,
+ -0.13062666356563568, 0.18007083237171173,
+ 0.7978920936584473, 0.18007083237171173,
+ -0.13062666356563568, 0.07206480950117111,
+ -0.0251916591078043, -1.132049690556083e-17,
+ 0.006678304169327021, -0.004960992839187384,
+ 0.0030193300917744637)
+ new_taps = filter.firdes.low_pass(1, 1, 0.4, 0.2)
+ self.assertFloatTuplesAlmostEqual(known_taps, new_taps, 5)
+
+ def test_low_pass_2(self):
+ known_taps = (0.0024871660862118006, -4.403502608370943e-18,
+ -0.014456653036177158, 0.0543283149600029,
+ -0.116202212870121, 0.17504146695137024,
+ 0.7976038455963135, 0.17504146695137024,
+ -0.116202212870121, 0.0543283149600029,
+ -0.014456653036177158, -4.403502608370943e-18,
+ 0.0024871660862118006)
+ new_taps = filter.firdes.low_pass_2(1, 1, 0.4, 0.2, 60)
+ self.assertFloatTuplesAlmostEqual(known_taps, new_taps, 5)
+
+ def test_high_pass(self):
+ known_taps = (-0.003062003292143345, 0.005031108390539885,
+ -0.0067726909182965755, 1.1480492661182674e-17,
+ 0.025547700002789497, -0.0730833187699318,
+ 0.13247284293174744, -0.18261581659317017,
+ 0.20229223370552063, -0.18261581659317017,
+ 0.13247284293174744, -0.0730833187699318,
+ 0.025547700002789497, 1.1480492661182674e-17,
+ -0.0067726909182965755, 0.005031108390539885,
+ -0.003062003292143345)
+ new_taps = filter.firdes.high_pass(1, 1, 0.4, 0.2)
+ self.assertFloatTuplesAlmostEqual(known_taps, new_taps, 5)
+
+ def test_high_pass_2(self):
+ known_taps = (-0.0027197482995688915, 4.815287179370254e-18,
+ 0.01580853760242462, -0.05940871313214302,
+ 0.1270686239004135, -0.1914101094007492,
+ 0.21804752945899963, -0.1914101094007492,
+ 0.1270686239004135, -0.05940871313214302,
+ 0.01580853760242462, 4.815287179370254e-18,
+ -0.0027197482995688915)
+ new_taps = filter.firdes.high_pass_2(1, 1, 0.4, 0.2, 60)
+ self.assertFloatTuplesAlmostEqual(known_taps, new_taps, 5)
+
+ def test_band_pass(self):
+ known_taps = (0.004961997736245394, -0.008152946829795837,
+ -0.004192151129245758, -5.749020235348687e-18,
+ 0.01581347920000553, 0.11843203753232956,
+ -0.21467317640781403, -0.11303528398275375,
+ 0.40520283579826355, -0.11303528398275375,
+ -0.21467317640781403, 0.11843203753232956,
+ 0.01581347920000553, -5.749020235348687e-18,
+ -0.004192151129245758, -0.008152946829795837,
+ 0.004961997736245394)
+ new_taps = filter.firdes.band_pass(1, 1, 0.2, 0.4, 0.2)
+ self.assertFloatTuplesAlmostEqual(known_taps, new_taps, 5)
+
+ def test_band_pass_2(self):
+ known_taps = (-0.001676854444667697, -2.4018533253972557e-18,
+ 0.009746716357767582, 0.09589414298534393,
+ -0.20510689914226532, -0.11801345646381378,
+ 0.4350462853908539, -0.11801345646381378,
+ -0.20510689914226532, 0.09589414298534393,
+ 0.009746716357767582, -2.4018533253972557e-18,
+ -0.001676854444667697)
+ new_taps = filter.firdes.band_pass_2(1, 1, 0.2, 0.4, 0.2, 60)
+ self.assertFloatTuplesAlmostEqual(known_taps, new_taps, 5)
+
+ def test_complex_band_pass(self):
+ known_taps = ((0.0024772135075181723+0.0017997993854805827j),
+ (-0.004070250317454338+0.002957213670015335j),
+ (-0.0020928815938532352-0.006441210396587849j),
+ (-2.8701231652956686e-18+2.805614574993832e-24j),
+ (0.007894645445048809-0.024297315627336502j),
+ (0.05912570655345917+0.04295721650123596j),
+ (-0.10717268288135529+0.07786571979522705j),
+ (-0.0564316064119339-0.17367789149284363j),
+ (0.20229223370552063-2.4115112751132983e-07j),
+ (-0.05643119290471077+0.17367802560329437j),
+ (-0.10717286914587021-0.07786546647548676j),
+ (0.05912560224533081-0.0429573580622673j),
+ (0.007894691079854965+0.024297300726175308j),
+ (-2.8701231652956686e-18+2.6687109203363464e-24j),
+ (-0.0020928694866597652+0.006441214121878147j),
+ (-0.004070255905389786-0.0029572059866040945j),
+ (0.0024772100150585175-0.0017998040420934558j))
+ new_taps = filter.firdes.complex_band_pass(1, 1, 0.2, 0.4, 0.2)
+ self.assertComplexTuplesAlmostEqual(known_taps, new_taps, 5)
+
+ def test_complex_band_pass_2(self):
+ known_taps = ((-0.0008404505206272006-0.0025866336654871702j),
+ (-1.2038217948425635e-18+1.1767648157397848e-24j),
+ (0.0048850891180336475-0.015034818090498447j),
+ (0.048062704503536224+0.03491950035095215j),
+ (-0.10280057787895203+0.07468919456005096j),
+ (-0.05914920195937157-0.18204176425933838j),
+ (0.21804752945899963-2.5993290364567656e-07j),
+ (-0.059148769825696945+0.18204189836978912j),
+ (-0.10280075669288635-0.07468894869089127j),
+ (0.04806262254714966-0.0349196158349514j),
+ (0.004885117989033461+0.015034808777272701j),
+ (-1.2038217948425635e-18+1.1193430388030685e-24j),
+ (-0.000840445572976023+0.002586635295301676j))
+ new_taps = filter.firdes.complex_band_pass_2(1, 1, 0.2, 0.4, 0.2, 60)
+ self.assertComplexTuplesAlmostEqual(known_taps, new_taps, 5)
+
+ def test_band_reject(self):
+ known_taps = (-0.004915320314466953, 0.008076251484453678,
+ 0.00415271520614624, 5.694938753309664e-18,
+ -0.01566472090780735, -0.11731793731451035,
+ 0.2126537412405014, 0.11197195947170258,
+ 0.6020866632461548, 0.11197195947170258,
+ 0.2126537412405014, -0.11731793731451035,
+ -0.01566472090780735, 5.694938753309664e-18,
+ 0.00415271520614624, 0.008076251484453678,
+ -0.004915320314466953)
+ new_taps = filter.firdes.band_reject(1, 1, 0.2, 0.4, 0.2)
+ self.assertFloatTuplesAlmostEqual(known_taps, new_taps, 5)
+
+ def test_band_reject_2(self):
+ known_taps = (0.0015371545450761914, 2.201753372137003e-18,
+ -0.00893471110612154, -0.08790513873100281,
+ 0.1880193054676056, 0.1081816703081131,
+ 0.5982034206390381, 0.1081816703081131,
+ 0.1880193054676056, -0.08790513873100281,
+ -0.00893471110612154, 2.201753372137003e-18,
+ 0.0015371545450761914)
+ new_taps = filter.firdes.band_reject_2(1, 1, 0.2, 0.4, 0.2, 60)
+ self.assertFloatTuplesAlmostEqual(known_taps, new_taps, 5)
+
+ def test_hilbert(self):
+ known_taps = (-0.010056184604763985, 0.0,
+ -0.08335155993700027, 0.0,
+ -0.5732954144477844, 0.0,
+ 0.5732954144477844, 0.0,
+ 0.08335155993700027, 0.0,
+ 0.010056184604763985)
+ new_taps = filter.firdes.hilbert(11)
+ self.assertFloatTuplesAlmostEqual(known_taps, new_taps, 5)
+
+ def test_root_raised_cosine(self):
+ known_taps = (-0.04609205573797226, -0.02069387212395668,
+ 0.050548505038022995, 0.14850808680057526,
+ 0.23387153446674347, 0.2677156329154968,
+ 0.23387153446674347, 0.14850808680057526,
+ 0.050548505038022995, -0.02069387212395668,
+ -0.04609205573797226)
+ new_taps = filter.firdes.root_raised_cosine(1, 4, 1, 0.35, 11)
+ self.assertFloatTuplesAlmostEqual(known_taps, new_taps, 5)
+
+ def test_gaussian(self):
+ known_taps = (0.0003600157215259969, 0.0031858310103416443,
+ 0.0182281993329525, 0.06743486225605011,
+ 0.16130395233631134, 0.24947398900985718,
+ 0.24947398900985718, 0.16130395233631134,
+ 0.06743486225605011, 0.0182281993329525,
+ 0.0031858310103416443, 0.0003600157215259969,
+ 2.630509879963938e-05)
+ new_taps = filter.firdes.gaussian(1, 4, 0.35, 13)
+ self.assertFloatTuplesAlmostEqual(known_taps, new_taps, 5)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_firdes, "test_firdes.xml")
+
diff --git a/gr-filter/python/qa_fractional_interpolator.py b/gr-filter/python/qa_fractional_interpolator.py
new file mode 100755
index 0000000000..9e0f685d80
--- /dev/null
+++ b/gr-filter/python/qa_fractional_interpolator.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+#
+# Copyright 2007,2010,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import filter_swig as filter
+import math
+
+class test_fractional_resampler(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_001_ff(self):
+ N = 10000 # number of samples to use
+ fs = 1000 # baseband sampling rate
+ rrate = 1.123 # resampling rate
+
+ freq = 10
+ signal = gr.sig_source_f(fs, gr.GR_SIN_WAVE, freq, 1)
+ head = gr.head(gr.sizeof_float, N)
+ op = filter.fractional_interpolator_ff(0, rrate)
+ snk = gr.vector_sink_f()
+
+ self.tb.connect(signal, head, op, snk)
+ self.tb.run()
+
+ Ntest = 5000
+ L = len(snk.data())
+ t = map(lambda x: float(x)/(fs/rrate), xrange(L))
+
+ phase = 0.1884
+ expected_data = map(lambda x: math.sin(2.*math.pi*freq*x+phase), t)
+
+ dst_data = snk.data()
+
+ self.assertFloatTuplesAlmostEqual(expected_data[-Ntest:], dst_data[-Ntest:], 3)
+
+
+ def test_002_cc(self):
+ N = 10000 # number of samples to use
+ fs = 1000 # baseband sampling rate
+ rrate = 1.123 # resampling rate
+
+ freq = 10
+ signal = gr.sig_source_c(fs, gr.GR_SIN_WAVE, freq, 1)
+ head = gr.head(gr.sizeof_gr_complex, N)
+ op = filter.fractional_interpolator_cc(0.0, rrate)
+ snk = gr.vector_sink_c()
+
+ self.tb.connect(signal, head, op, snk)
+ self.tb.run()
+
+ Ntest = 5000
+ L = len(snk.data())
+ t = map(lambda x: float(x)/(fs/rrate), xrange(L))
+
+ phase = 0.1884
+ expected_data = map(lambda x: math.cos(2.*math.pi*freq*x+phase) + \
+ 1j*math.sin(2.*math.pi*freq*x+phase), t)
+
+ dst_data = snk.data()
+
+ self.assertComplexTuplesAlmostEqual(expected_data[-Ntest:], dst_data[-Ntest:], 3)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_fractional_resampler, "test_fractional_resampler.xml")
diff --git a/gr-filter/python/qa_freq_xlating_fir_filter.py b/gr-filter/python/qa_freq_xlating_fir_filter.py
new file mode 100755
index 0000000000..ee38eb7dff
--- /dev/null
+++ b/gr-filter/python/qa_freq_xlating_fir_filter.py
@@ -0,0 +1,445 @@
+#!/usr/bin/env python
+#
+# Copyright 2008,2010,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+from gnuradio import gr, gr_unittest
+import filter_swig as filter
+import cmath, math
+
+class test_freq_xlating_filter(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block ()
+
+ def tearDown(self):
+ self.tb = None
+
+ def generate_ccf_source(self):
+ self.fs = fs = 1
+ self.fc = fc = 0.3
+ self.bw = bw = 0.1
+ self.taps = filter.firdes.low_pass(1, fs, bw, bw/4)
+ times = xrange(100)
+ self.src_data = map(lambda t: cmath.exp(-2j*cmath.pi*fc/fs*(t/100.0)), times)
+
+ def generate_ccc_source(self):
+ self.fs = fs = 1
+ self.fc = fc = 0.3
+ self.bw = bw = 0.1
+ self.taps = filter.firdes.complex_band_pass(1, fs, -bw/2, bw/2, bw/4)
+ times = xrange(100)
+ self.src_data = map(lambda t: cmath.exp(-2j*cmath.pi*fc/fs*(t/100.0)), times)
+
+ def generate_fcf_source(self):
+ self.fs = fs = 1
+ self.fc = fc = 0.3
+ self.bw = bw = 0.1
+ self.taps = filter.firdes.low_pass(1, fs, bw, bw/4)
+ times = xrange(100)
+ self.src_data = map(lambda t: math.sin(2*cmath.pi*fc/fs*(t/100.0)), times)
+
+ def generate_fcc_source(self):
+ self.fs = fs = 1
+ self.fc = fc = 0.3
+ self.bw = bw = 0.1
+ self.taps = filter.firdes.complex_band_pass(1, fs, -bw/2, bw/2, bw/4)
+ times = xrange(100)
+ self.src_data = map(lambda t: math.sin(2*cmath.pi*fc/fs*(t/100.0)), times)
+
+ def generate_scf_source(self):
+ self.fs = fs = 1
+ self.fc = fc = 0.3
+ self.bw = bw = 0.1
+ self.taps = filter.firdes.low_pass(1, fs, bw, bw/4)
+ times = xrange(100)
+ self.src_data = map(lambda t: int(100*math.sin(2*cmath.pi*fc/fs*(t/100.0))), times)
+
+ def generate_scc_source(self):
+ self.fs = fs = 1
+ self.fc = fc = 0.3
+ self.bw = bw = 0.1
+ self.taps = filter.firdes.complex_band_pass(1, fs, -bw/2, bw/2, bw/4)
+ times = xrange(100)
+ self.src_data = map(lambda t: int(100*math.sin(2*cmath.pi*fc/fs*(t/100.0))), times)
+
+
+ def test_fir_filter_ccf_001(self):
+ self.generate_ccf_source()
+ expected_data = ((0.001697700354270637+0.004312471952289343j),
+ (0.003520616563037038-0.003014103975147009j),
+ (0.004252811893820763-0.008337559178471565j),
+ (0.0030743128154426813-0.010262271389365196j),
+ (0.0007344777695834637-0.007861139252781868j),
+ (-0.0011067686136811972-0.0028924935031682253j),
+ (-0.002371778478845954+0.0019914964213967323j),
+ (-0.003023319412022829+0.005717850290238857j),
+ (-0.0021738125942647457+0.007211698684841394j),
+ (-0.0004628606839105487+0.005501383915543556j),
+ (0.0007428556564264+0.0019867848604917526j),
+ (0.001634795218706131-0.0013514887541532516j),
+ (0.002205110155045986-0.00402155052870512j),
+ (0.0015480631263926625-0.005179159343242645j),
+ (0.00026722141774371266-0.003887997241690755j),
+ (-0.0004911854630336165-0.0013578246580436826j),
+ (-0.0011226939968764782+0.0009080552263185382j),
+ (-0.0016229727771133184+0.0028335191309452057j),
+ (-0.0010890064295381308+0.0037298379465937614j),
+ (-0.00012392725329846144+0.0027196139562875032j))
+ src = gr.vector_source_c(self.src_data)
+ op = filter.freq_xlating_fir_filter_ccf(1, self.taps, self.fc, self.fs)
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data[-20:], 5)
+
+ def test_fir_filter_ccf_002(self):
+ self.generate_ccf_source()
+ expected_data = ((6.419439159799367e-05-0.0006292851758189499j),
+ (-0.00037074743886478245+0.0013245552545413375j),
+ (0.0006853155209682882-0.0023769831750541925j),
+ (-0.001427714480087161+0.002608160488307476j),
+ (0.0015907397028058767-0.000811046629678458j),
+ (-0.0004226673918310553-0.0024389736354351044j),
+ (-0.0013841050677001476+0.006231029983609915j),
+ (0.0035029184073209763-0.009738259017467499j),
+ (-0.005924836732447147+0.010320881381630898j),
+ (0.006831614300608635-0.003950652200728655j),
+ (-0.0021247887052595615-0.015604906715452671j),
+ (-0.04283163696527481+0.09995654970407486j),
+ (-0.01391829177737236+0.07924056798219681j),
+ (0.010886997915804386-0.02463012933731079j),
+ (-0.0056075905449688435+0.004998659715056419j),
+ (0.0016976913902908564+0.004312459379434586j),
+ (0.0007344821933656931-0.007861112244427204j),
+ (-0.002173811662942171+0.007211671676486731j),
+ (0.0022051059640944004-0.00402153329923749j),
+ (-0.0011226903880015016+0.0009080505697056651j))
+ src = gr.vector_source_c(self.src_data)
+ op = filter.freq_xlating_fir_filter_ccf(4, self.taps, self.fc, self.fs)
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data[-20:], 5)
+
+ def test_fir_filter_ccc_001(self):
+ self.generate_ccc_source()
+ expected_data = ((0.0036842757836-0.0114002721384j),
+ (0.00324621866457-0.0108166672289j),
+ (0.00206564785913-0.00923090614378j),
+ (0.00109899020754-0.00656201224774j),
+ (0.000506619049702-0.00402844604105j),
+ (-0.000523390364833-0.00166808743961j),
+ (-0.00140534969978+0.00103991874494j),
+ (-0.00154365820345+0.00315759982914j),
+ (-0.00180402118713+0.00427215453237j),
+ (-0.00216706306674+0.00524478312582j),
+ (-0.00178848754149+0.0057489364408j),
+ (-0.00129876169376+0.00512680830434j),
+ (-0.00122803379782+0.00427244976163j),
+ (-0.000722666736692+0.00351428100839j),
+ (5.53092104383e-05+0.00207865727134j),
+ (0.000227351076319+0.000517217209563j),
+ (0.000414477253798-0.000383921898901j),
+ (0.000998671515845-0.00135387131013j),
+ (0.00104933069088-0.00243046949618j),
+ (0.000765930046327-0.0026717747096j))
+ src = gr.vector_source_c(self.src_data)
+ op = filter.freq_xlating_fir_filter_ccc(1, self.taps, self.fc, self.fs)
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data[-20:], 5)
+
+ def test_fir_filter_ccc_002(self):
+ self.generate_ccc_source()
+ expected_data = ((-0.000650451984257+0.00120697380044j),
+ (-9.59713361226e-05+0.00102412770502j),
+ (0.000958710326813-0.00145424995571j),
+ (0.000901343999431-0.00290832063183j),
+ (-0.000822560978122+0.000296717538731j),
+ (-0.00211223773658+0.00519825471565j),
+ (-0.00037001183955+0.00358242215589j),
+ (0.00327983591706-0.00616005761549j),
+ (0.00356886954978-0.0117237549275j),
+ (-0.00328874029219+0.00182871113066j),
+ (-0.0139285130426+0.0320657044649j),
+ (-0.0198133718222+0.0562113076448j),
+ (-0.0157803222537+0.0530290603638j),
+ (-0.00550725404173+0.0255754813552j),
+ (0.00252919178456-0.00232240976766j),
+ (0.00368427345529-0.0114002330229j),
+ (0.000506620621309-0.00402843113989j),
+ (-0.00180401885882+0.00427213776857j),
+ (-0.00122803344857+0.00427243299782j),
+ (0.000414476031438-0.000383919978049j))
+ src = gr.vector_source_c(self.src_data)
+ op = filter.freq_xlating_fir_filter_ccc(4, self.taps, self.fc, self.fs)
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data[-20:], 5)
+
+ def test_fir_filter_fcf_001(self):
+ self.generate_fcf_source()
+ expected_data = ((0.000247188087087-0.000157509770361j),
+ (-0.000155229790835-0.000246197130764j),
+ (-0.000264906557277+0.000174603672349j),
+ (6.99016964063e-05+0.000174961372977j),
+ (-5.48477692064e-05-0.0001131295503j),
+ (-0.000237467131228+0.000118011368613j),
+ (0.000136614587973+0.000229531884543j),
+ (0.000229347482673-0.000166581812664j),
+ (-0.000106010869786-0.000150042149471j),
+ (2.92293734674e-05+0.000142060467624j),
+ (0.000228707227507-9.30760797928e-05j),
+ (-0.000124306126963-0.000216641055886j),
+ (-0.000204823678359+0.00016052465071j),
+ (0.00012825592421+0.000133123627165j),
+ (-1.18284006021e-05-0.000159015646204j),
+ (-0.000219973371713+7.5438656495e-05j),
+ (0.000114713984658+0.000205190401175j),
+ (0.000185727752978-0.000154630601173j),
+ (-0.000141745767905-0.000120098840853j),
+ (-3.9850056055e-07+0.000168364742422j))
+ src = gr.vector_source_f(self.src_data)
+ op = filter.freq_xlating_fir_filter_fcf(1, self.taps, self.fc, self.fs)
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data[-20:], 5)
+
+ def test_fir_filter_fcf_002(self):
+ self.generate_fcf_source()
+ expected_data = ((7.3052920925e-05-3.91741014028e-06j),
+ (3.11913172482e-05-0.000109872074972j),
+ (-0.000128646017401-3.49857727997e-05j),
+ (-5.49546712136e-05+8.96326746442e-05j),
+ (5.14321582159e-05+9.64698920143e-05j),
+ (0.000120189361041+2.4231892894e-05j),
+ (0.000100405508419-0.000223224604269j),
+ (-0.000274751859251-2.33274622587e-05j),
+ (1.52600114234e-06+0.000133301247843j),
+ (3.77224641852e-05+5.29596509296e-05j),
+ (-3.60160379387e-06+0.000247975171078j),
+ (0.00113093166146-0.000663110695314j),
+ (0.00059568521101-0.00099650840275j),
+ (-0.000475480686873+0.000250602373853j),
+ (0.000191397906747+0.000271986238658j),
+ (0.000247183139436-0.000157510468853j),
+ (-5.48357638763e-05-0.000113135029096j),
+ (-0.00010601492977-0.00015005269961j),
+ (-0.000204817260965+0.000160534662427j),
+ (0.000114742244477+0.000205190313864j))
+ src = gr.vector_source_f(self.src_data)
+ op = filter.freq_xlating_fir_filter_fcf(4, self.taps, self.fc, self.fs)
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data[-20:], 5)
+
+ def test_fir_filter_fcc_001(self):
+ self.generate_fcc_source()
+ expected_data = ((-0.000337088305969+7.46004516259e-05j),
+ (-5.63409266761e-05+0.000301144464174j),
+ (9.16960561881e-05-2.89259278361e-05j),
+ (-0.000231866899412-6.25764005235e-05j),
+ (-0.000116414688819+0.000258557556663j),
+ (0.000206079319469+5.05045172758e-05j),
+ (-3.85114690289e-05-0.00019276549574j),
+ (-0.000146380873048+0.000112079876999j),
+ (0.000215423395275+0.000116706331028j),
+ (0.000136050162837-0.000232611957472j),
+ (-0.000155499437824-5.41604022146e-05j),
+ (0.000106907449663+0.00016310159117j),
+ (0.000224392410018-0.000156331108883j),
+ (-0.000131131906528-0.000172063446371j),
+ (-5.92393880652e-05+0.00016801241145j),
+ (0.000214921761653-5.32235890205e-06j),
+ (-5.96960526309e-05-0.000211164733628j),
+ (-0.000193948610104+0.000113364716526j),
+ (0.000134820176754+0.000142527525895j),
+ (4.74465123261e-05-0.000175131688593j))
+ src = gr.vector_source_f(self.src_data)
+ op = filter.freq_xlating_fir_filter_fcc(1, self.taps, self.fc, self.fs)
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data[-20:], 5)
+
+ def test_fir_filter_fcc_002(self):
+ self.generate_fcc_source()
+ expected_data = ((-6.94218761055e-05-9.90489479591e-06j),
+ (-2.56973435171e-05+8.05932795629e-05j),
+ (7.01698663761e-05+7.36373840482e-05j),
+ (7.57163215894e-05-4.65324592369e-05j),
+ (-3.01657128148e-05-0.000122838056996j),
+ (-9.53659764491e-05-3.73945695173e-05j),
+ (-2.33501577895e-05+0.000109135726234j),
+ (6.65136758471e-05+0.000125709688291j),
+ (3.08501912514e-05-9.16842873266e-06j),
+ (-2.64703612629e-05-0.000135892929393j),
+ (0.000136643866426-0.000162003751029j),
+ (0.000501801609062-0.000185820827028j),
+ (0.000694551155902-0.000299874518532j),
+ (0.000424396857852-0.00038379128091j),
+ (-9.1786707344e-05-0.000242479465669j),
+ (-0.000337087287335+7.45999423089e-05j),
+ (-0.000116414521472+0.000258556567132j),
+ (0.000215422536712+0.000116706112749j),
+ (0.000224391726078-0.000156330308528j),
+ (-5.96956087975e-05-0.000211163976928j))
+ src = gr.vector_source_f(self.src_data)
+ op = filter.freq_xlating_fir_filter_fcc(4, self.taps, self.fc, self.fs)
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data[-20:], 5)
+
+ def test_fir_filter_scf_001(self):
+ self.generate_scf_source()
+ expected_data = ((-0.0330070219934+0.101965591311j),
+ (-0.0484239049256+0.0872343629599j),
+ (-0.0214109234512+0.102555386722j),
+ (0.0484058149159+0.0557125210762j),
+ (0.0574690811336-0.0350844524801j),
+ (0.0365394353867-0.0802438184619j),
+ (0.0453781634569-0.130992040038j),
+ (0.00801951438189-0.214278846979j),
+ (-0.0770946145058-0.230616629124j),
+ (-0.105601429939-0.190731987357j),
+ (-0.105361394584-0.177761554718j),
+ (-0.131518915296-0.136102750897j),
+ (-0.103761836886-0.0382263250649j),
+ (-0.0167790111154+0.0152206514031j),
+ (0.0277570039034+0.0300403907895j),
+ (0.056065287441+0.0806603953242j),
+ (0.118084669113+0.104863211513j),
+ (0.128281414509+0.0677760615945j),
+ (0.0748447552323+0.0619902014732j),
+ (0.0512856245041+0.0775099247694j))
+ src = gr.vector_source_s(self.src_data)
+ op = filter.freq_xlating_fir_filter_scf(1, self.taps, self.fc, self.fs)
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data[-20:], 5)
+
+ def test_fir_filter_scf_002(self):
+ self.generate_scf_source()
+ expected_data = ((0.00824625696987-1.50158575707e-05j),
+ (0.0020101047121-0.0116540221497j),
+ (-0.0126378880814-0.00259830290452j),
+ (-0.00363933457993+0.00837504956871j),
+ (0.00107023562305+0.00915473792702j),
+ (0.0169738996774+0.00422182958573j),
+ (0.00630031805485-0.025423232466j),
+ (-0.0283014029264+0.00104465708137j),
+ (0.00890890974551+0.0115978596732j),
+ (-0.0142687577754+0.00306978379376j),
+ (0.02845691517+0.0331163145602j),
+ (0.0538152232766-0.0908300876617j),
+ (-0.0843691527843-0.0956566259265j),
+ (0.0476895272732+0.0747984498739j),
+ (0.0898786485195+0.082478672266j),
+ (-0.0330070182681+0.101965606213j),
+ (0.0574697069824-0.0350842289627j),
+ (-0.0770940706134-0.230615705252j),
+ (-0.103762261569-0.0382265634835j),
+ (0.11808334291+0.104863762856j))
+ src = gr.vector_source_s(self.src_data)
+ op = filter.freq_xlating_fir_filter_scf(4, self.taps, self.fc, self.fs)
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data[-20:], 5)
+
+ def test_fir_filter_scc_001(self):
+ self.generate_scc_source()
+ expected_data = ((-0.00775564694777+0.0437113791704j),
+ (0.0108830630779+0.0433648750186j),
+ (0.015553932637-0.0133284125477j),
+ (-0.0264905355871-0.0403266139328j),
+ (-0.0243480335921-0.03030154109j),
+ (-0.000327925226884-0.069333948195j),
+ (-0.0306392069906-0.107313856483j),
+ (-0.0452371090651-0.0854917764664j),
+ (-0.0108894333243-0.0875641107559j),
+ (-0.0182112380862-0.118961036205j),
+ (-0.0447825863957-0.0922874584794j),
+ (-0.0147479763255-0.0572904124856j),
+ (0.00204290449619-0.0721436738968j),
+ (-0.027713002637-0.0548989400268j),
+ (-0.0149045493454-0.00210141134448j),
+ (0.0176361314952-0.00149522523861j),
+ (-0.00527482619509-0.00698099425063j),
+ (-0.0151527002454+0.036265052855j),
+ (0.0199296213686+0.0452499426901j),
+ (0.0122985243797+0.0143278446048j))
+ src = gr.vector_source_s(self.src_data)
+ op = filter.freq_xlating_fir_filter_scc(1, self.taps, self.fc, self.fs)
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data[-20:], 5)
+
+ def test_fir_filter_scc_002(self):
+ self.generate_scc_source()
+ expected_data = ((-0.0080680437386-0.00158522999845j),
+ (-0.0037795654498+0.00733159901574j),
+ (0.00842926371843+0.00777021236718j),
+ (0.0112090632319-0.00249325321056j),
+ (-0.0027476802934-0.0115710813552j),
+ (-0.0158688724041-0.00715934624895j),
+ (-0.00802888441831+0.00620818417519j),
+ (0.0131985172629+0.0149175003171j),
+ (0.0190298333764+0.00956719089299j),
+ (-0.00112380902283-0.00936658866704j),
+ (-0.0204226914793-0.0333464704454j),
+ (-0.00695514678955-0.0437445007265j),
+ (0.0314490310848-0.0207983348519j),
+ (0.0529675260186+0.0302227605134j),
+ (0.0317338332534+0.0667510479689j),
+ (-0.00775565672666+0.0437112376094j),
+ (-0.024347923696-0.0303014591336j),
+ (-0.0108893103898-0.0875638127327j),
+ (0.00204296782613-0.0721434056759j),
+ (-0.00527479872108-0.00698097236454j))
+ src = gr.vector_source_s(self.src_data)
+ op = filter.freq_xlating_fir_filter_scc(4, self.taps, self.fc, self.fs)
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_data, result_data[-20:], 5)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_freq_xlating_filter, "test_freq_xlating_filter.xml")
+
diff --git a/gr-filter/python/qa_hilbert.py b/gr-filter/python/qa_hilbert.py
new file mode 100755
index 0000000000..b460b6438f
--- /dev/null
+++ b/gr-filter/python/qa_hilbert.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import filter_swig as filter
+import math
+
+class test_hilbert(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block ()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_hilbert(self):
+ tb = self.tb
+ ntaps = 51
+ sampling_freq = 100
+
+ expected_result = ( -1.4678005338941702e-11j,
+ -0.0011950774351134896j,
+ -0.0019336787518113852j,
+ -0.0034673355985432863j,
+ -0.0036765895783901215j,
+ -0.004916108213365078j,
+ -0.0042778430506587029j,
+ -0.006028641015291214j,
+ -0.005476709920912981j,
+ -0.0092810001224279404j,
+ -0.0095402700826525688j,
+ -0.016060983762145042j,
+ -0.016446959227323532j,
+ -0.02523401565849781j,
+ -0.024382550269365311j,
+ -0.035477779805660248j,
+ -0.033021725714206696j,
+ -0.048487484455108643j,
+ -0.04543270543217659j,
+ -0.069477587938308716j,
+ -0.066984444856643677j,
+ -0.10703597217798233j,
+ -0.10620346665382385j,
+ -0.1852707713842392j,
+ -0.19357112050056458j,
+ (7.2191945754696007e-09 -0.50004088878631592j),
+ (0.58778399229049683 -0.6155126690864563j),
+ (0.95105588436126709 -0.12377222627401352j),
+ (0.95105588436126709 +0.41524654626846313j),
+ (0.5877838134765625 +0.91611981391906738j),
+ (5.8516356205018383e-09 +1.0670661926269531j),
+ (-0.5877840518951416 +0.87856143712997437j),
+ (-0.95105588436126709 +0.35447561740875244j),
+ (-0.95105588436126709 -0.26055556535720825j),
+ (-0.5877838134765625 -0.77606213092803955j),
+ (-8.7774534307527574e-09 -0.96460390090942383j),
+ (0.58778399229049683 -0.78470128774642944j),
+ (0.95105588436126709 -0.28380891680717468j),
+ (0.95105588436126709 +0.32548999786376953j),
+ (0.5877838134765625 +0.82514488697052002j),
+ (1.4629089051254596e-08 +1.0096219778060913j),
+ (-0.5877840518951416 +0.81836479902267456j),
+ (-0.95105588436126709 +0.31451958417892456j),
+ (-0.95105588436126709 -0.3030143678188324j),
+ (-0.5877838134765625 -0.80480599403381348j),
+ (-1.7554906861505515e-08 -0.99516552686691284j),
+ (0.58778399229049683 -0.80540722608566284j),
+ (0.95105582475662231 -0.30557557940483093j),
+ (0.95105588436126709 +0.31097668409347534j),
+ (0.5877838134765625 +0.81027895212173462j),
+ (2.3406542482007353e-08 +1.0000816583633423j),
+ (-0.5877840518951416 +0.80908381938934326j),
+ (-0.95105588436126709 +0.30904293060302734j),
+ (-0.95105588436126709 -0.30904296040534973j),
+ (-0.5877838134765625 -0.80908387899398804j),
+ (-2.6332360292258272e-08 -1.0000815391540527j),
+ (0.58778399229049683 -0.80908381938934326j),
+ (0.95105582475662231 -0.30904299020767212j),
+ (0.95105588436126709 +0.30904293060302734j),
+ (0.5877838134765625 +0.80908381938934326j),
+ (3.218399768911695e-08 +1.0000815391540527j))
+
+
+ src1 = gr.sig_source_f(sampling_freq, gr.GR_SIN_WAVE,
+ sampling_freq * 0.10, 1.0)
+
+ head = gr.head(gr.sizeof_float, int (ntaps + sampling_freq * 0.10))
+ hilb = filter.hilbert_fc(ntaps)
+ dst1 = gr.vector_sink_c()
+ tb.connect(src1, head)
+ tb.connect(head, hilb)
+ tb.connect(hilb, dst1)
+ tb.run()
+ dst_data = dst1.data()
+ self.assertComplexTuplesAlmostEqual (expected_result, dst_data, 5)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_hilbert, "test_hilbert.xml")
diff --git a/gr-filter/python/qa_iir_filter.py b/gr-filter/python/qa_iir_filter.py
new file mode 100755
index 0000000000..645c4b66e7
--- /dev/null
+++ b/gr-filter/python/qa_iir_filter.py
@@ -0,0 +1,157 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import filter_swig as filter
+
+class test_iir_filter(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_iir_direct_001(self):
+ src_data = (1, 2, 3, 4, 5, 6, 7, 8)
+ fftaps = ()
+ fbtaps = ()
+ expected_result = (0, 0, 0, 0, 0, 0, 0, 0)
+ src = gr.vector_source_f(src_data)
+ op = filter.iir_filter_ffd(fftaps, fbtaps)
+ dst = gr.vector_sink_f()
+ self.tb.connect(src, op)
+ self.tb.connect(op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertFloatTuplesAlmostEqual(expected_result, result_data)
+
+ def test_iir_direct_002(self):
+ src_data = (1, 2, 3, 4, 5, 6, 7, 8)
+ fftaps = (2,)
+ fbtaps = (0,)
+ expected_result = (2, 4, 6, 8, 10, 12, 14, 16)
+ src = gr.vector_source_f(src_data)
+ op = filter.iir_filter_ffd(fftaps, fbtaps)
+ dst = gr.vector_sink_f()
+ self.tb.connect(src, op)
+ self.tb.connect(op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertFloatTuplesAlmostEqual(expected_result, result_data)
+
+ def test_iir_direct_003(self):
+ src_data = (1, 2, 3, 4, 5, 6, 7, 8)
+ fftaps = (2, 11)
+ fbtaps = (0, 0)
+ expected_result = (2, 15, 28, 41, 54, 67, 80, 93)
+ src = gr.vector_source_f(src_data)
+ op = filter.iir_filter_ffd(fftaps, fbtaps)
+ dst = gr.vector_sink_f()
+ self.tb.connect(src, op)
+ self.tb.connect(op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertFloatTuplesAlmostEqual(expected_result, result_data)
+
+ def test_iir_direct_004(self):
+ src_data = (1, 2, 3, 4, 5, 6, 7, 8)
+ fftaps = (2, 11)
+ fbtaps = (0, -1)
+ expected_result = (2, 13, 15, 26, 28, 39, 41, 52)
+ src = gr.vector_source_f(src_data)
+ op = filter.iir_filter_ffd(fftaps, fbtaps)
+ dst = gr.vector_sink_f()
+ self.tb.connect(src, op)
+ self.tb.connect(op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertFloatTuplesAlmostEqual(expected_result, result_data)
+
+ def test_iir_direct_005(self):
+ src_data = (1, 2, 3, 4, 5, 6, 7, 8)
+ fftaps = (2, 11, 0)
+ fbtaps = (0, -1, 3)
+ expected_result = (2, 13, 21, 59, 58, 186, 68, 583)
+ src = gr.vector_source_f(src_data)
+ op = filter.iir_filter_ffd(fftaps, fbtaps)
+ dst = gr.vector_sink_f()
+ self.tb.connect(src, op)
+ self.tb.connect(op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertFloatTuplesAlmostEqual(expected_result, result_data)
+
+ def test_iir_direct_006(self):
+ src_data = (1, 2, 3, 4, 5, 6, 7, 8)
+ expected_result = (2, 13, 21, 59, 58, 186, 68, 583)
+ fftaps = (2, 1)
+ fbtaps = (0, -1)
+ src = gr.vector_source_f(src_data)
+ op = filter.iir_filter_ffd(fftaps, fbtaps)
+ fftaps = (2, 11, 0)
+ fbtaps = (0, -1, 3)
+ op.set_taps(fftaps, fbtaps)
+ dst = gr.vector_sink_f()
+ self.tb.connect(src, op)
+ self.tb.connect(op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertFloatTuplesAlmostEqual(expected_result, result_data)
+
+ def test_iir_direct_007(self):
+ src_data = (1, 2, 3, 4, 5, 6, 7, 8)
+ expected_result = (2,2,5,5,8,8,11,11)
+ fftaps = (2, 1)
+ fbtaps = (0, -1)
+ src = gr.vector_source_f(src_data)
+ op = filter.iir_filter_ffd(fftaps, fbtaps)
+ fftaps = (2,0,1)
+ fbtaps = (0, -1)
+ op.set_taps(fftaps, fbtaps)
+ dst = gr.vector_sink_f()
+ self.tb.connect(src, op)
+ self.tb.connect(op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertFloatTuplesAlmostEqual(expected_result, result_data)
+
+ def test_iir_direct_008(self):
+ src_data = (1, 2, 3, 4, 5, 6, 7, 8)
+ expected_result = (2,4,4,10,18,14,26,56)
+ fftaps = (2,)
+ fbtaps = (0, 1)
+ src = gr.vector_source_f(src_data)
+ op = filter.iir_filter_ffd(fftaps, fbtaps)
+ fftaps_data = (1)
+ fbtaps = (0,0, -1,3)
+ op.set_taps(fftaps, fbtaps)
+ dst = gr.vector_sink_f()
+ self.tb.connect(src, op)
+ self.tb.connect(op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_iir_filter, "test_iir_filter.xml")
+
diff --git a/gr-filter/python/qa_interp_fir_filter.py b/gr-filter/python/qa_interp_fir_filter.py
new file mode 100755
index 0000000000..839330539b
--- /dev/null
+++ b/gr-filter/python/qa_interp_fir_filter.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import filter_swig as filter
+import math
+
+class test_interp_fir_filter(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_fff(self):
+ taps = [1, 10, 100, 1000, 10000]
+ src_data = (0, 2, 3, 5, 7, 11, 13, 17)
+ interpolation = 3
+ xr = (0,0,0,0,
+ 2,20,200,2003,20030,
+ 300,3005,30050,
+ 500,5007,50070,
+ 700,7011,70110,
+ 1100,11013,110130,
+ 1300,13017,130170)
+ expected_result = tuple([float(x) for x in xr])
+
+ src = gr.vector_source_f(src_data)
+ op = filter.interp_fir_filter_fff(interpolation, taps)
+ dst = gr.vector_sink_f()
+ self.tb.connect(src, op)
+ self.tb.connect(op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ L = min(len(result_data), len(expected_result))
+ self.assertEqual(expected_result[0:L], result_data[0:L])
+
+if __name__ == '__main__':
+ gr_unittest.run(test_interp_fir_filter, "test_interp_fir_filter.xml")
+
diff --git a/gr-filter/python/qa_pfb_arb_resampler.py b/gr-filter/python/qa_pfb_arb_resampler.py
new file mode 100755
index 0000000000..a4e22f4c02
--- /dev/null
+++ b/gr-filter/python/qa_pfb_arb_resampler.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import filter_swig as filter
+import math
+
+class test_pfb_arb_resampler(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_fff_000(self):
+ N = 1000 # number of samples to use
+ fs = 1000 # baseband sampling rate
+ rrate = 1.123 # resampling rate
+
+ nfilts = 32
+ taps = filter.firdes.low_pass_2(nfilts, nfilts*fs, fs/2, fs/10,
+ attenuation_dB=80,
+ window=filter.firdes.WIN_BLACKMAN_hARRIS)
+
+ freq = 100
+ signal = gr.sig_source_f(fs, gr.GR_SIN_WAVE, freq, 1)
+ head = gr.head(gr.sizeof_float, N)
+ pfb = filter.pfb_arb_resampler_fff(rrate, taps)
+ snk = gr.vector_sink_f()
+
+ self.tb.connect(signal, head, pfb, snk)
+ self.tb.run()
+
+ Ntest = 50
+ L = len(snk.data())
+ t = map(lambda x: float(x)/(fs*rrate), xrange(L))
+
+ phase = 0.53013
+ expected_data = map(lambda x: math.sin(2.*math.pi*freq*x+phase), t)
+
+ dst_data = snk.data()
+ self.assertFloatTuplesAlmostEqual(expected_data[-Ntest:], dst_data[-Ntest:], 3)
+
+ def test_ccf_000(self):
+ N = 1000 # number of samples to use
+ fs = 1000 # baseband sampling rate
+ rrate = 1.123 # resampling rate
+
+ nfilts = 32
+ taps = filter.firdes.low_pass_2(nfilts, nfilts*fs, fs/2, fs/10,
+ attenuation_dB=80,
+ window=filter.firdes.WIN_BLACKMAN_hARRIS)
+
+ freq = 100
+ signal = gr.sig_source_c(fs, gr.GR_SIN_WAVE, freq, 1)
+ head = gr.head(gr.sizeof_gr_complex, N)
+ pfb = filter.pfb_arb_resampler_ccf(rrate, taps)
+ snk = gr.vector_sink_c()
+
+ self.tb.connect(signal, head, pfb, snk)
+ self.tb.run()
+
+ Ntest = 50
+ L = len(snk.data())
+ t = map(lambda x: float(x)/(fs*rrate), xrange(L))
+
+ phase = 0.53013
+ expected_data = map(lambda x: math.cos(2.*math.pi*freq*x+phase) + \
+ 1j*math.sin(2.*math.pi*freq*x+phase), t)
+
+ dst_data = snk.data()
+ self.assertComplexTuplesAlmostEqual(expected_data[-Ntest:], dst_data[-Ntest:], 3)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_pfb_arb_resampler, "test_pfb_arb_resampler.xml")
diff --git a/gr-filter/python/qa_pfb_channelizer.py b/gr-filter/python/qa_pfb_channelizer.py
new file mode 100755
index 0000000000..c0ed8327df
--- /dev/null
+++ b/gr-filter/python/qa_pfb_channelizer.py
@@ -0,0 +1,104 @@
+#!/usr/bin/env python
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import filter_swig as filter
+import math
+
+class test_pfb_channelizer(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_000(self):
+ N = 1000 # number of samples to use
+ M = 5 # Number of channels to channelize
+ fs = 1000 # baseband sampling rate
+ ifs = M*fs # input samp rate to channelizer
+
+ taps = filter.firdes.low_pass_2(1, ifs, 500, 50,
+ attenuation_dB=80,
+ window=filter.firdes.WIN_BLACKMAN_hARRIS)
+
+ signals = list()
+ add = gr.add_cc()
+ freqs = [-200, -100, 0, 100, 200]
+ for i in xrange(len(freqs)):
+ f = freqs[i] + (M/2-M+i+1)*fs
+ signals.append(gr.sig_source_c(ifs, gr.GR_SIN_WAVE, f, 1))
+ self.tb.connect(signals[i], (add,i))
+
+ head = gr.head(gr.sizeof_gr_complex, N)
+ s2ss = gr.stream_to_streams(gr.sizeof_gr_complex, M)
+ pfb = filter.pfb_channelizer_ccf(M, taps, 1)
+
+ self.tb.connect(add, head, s2ss)
+
+ snks = list()
+ for i in xrange(M):
+ snks.append(gr.vector_sink_c())
+ self.tb.connect((s2ss,i), (pfb,i))
+ self.tb.connect((pfb, i), snks[i])
+
+ self.tb.run()
+
+ Ntest = 50
+ L = len(snks[0].data())
+ t = map(lambda x: float(x)/fs, xrange(L))
+
+ # Adjusted phase rotations for data
+ p0 = 0
+ p1 = math.pi*0.51998885
+ p2 = -math.pi*0.96002233
+ p3 = math.pi*0.96002233
+ p4 = -math.pi*0.51998885
+
+ # Create known data as complex sinusoids at the different baseband freqs
+ # the different channel numbering is due to channelizer output order.
+ expected0_data = map(lambda x: math.cos(2.*math.pi*freqs[2]*x+p0) + \
+ 1j*math.sin(2.*math.pi*freqs[2]*x+p0), t)
+ expected1_data = map(lambda x: math.cos(2.*math.pi*freqs[3]*x+p1) + \
+ 1j*math.sin(2.*math.pi*freqs[3]*x+p1), t)
+ expected2_data = map(lambda x: math.cos(2.*math.pi*freqs[4]*x+p2) + \
+ 1j*math.sin(2.*math.pi*freqs[4]*x+p2), t)
+ expected3_data = map(lambda x: math.cos(2.*math.pi*freqs[0]*x+p3) + \
+ 1j*math.sin(2.*math.pi*freqs[0]*x+p3), t)
+ expected4_data = map(lambda x: math.cos(2.*math.pi*freqs[1]*x+p4) + \
+ 1j*math.sin(2.*math.pi*freqs[1]*x+p4), t)
+
+ dst0_data = snks[0].data()
+ dst1_data = snks[1].data()
+ dst2_data = snks[2].data()
+ dst3_data = snks[3].data()
+ dst4_data = snks[4].data()
+
+ self.assertComplexTuplesAlmostEqual(expected0_data[-Ntest:], dst0_data[-Ntest:], 3)
+ self.assertComplexTuplesAlmostEqual(expected1_data[-Ntest:], dst1_data[-Ntest:], 3)
+ self.assertComplexTuplesAlmostEqual(expected2_data[-Ntest:], dst2_data[-Ntest:], 3)
+ self.assertComplexTuplesAlmostEqual(expected3_data[-Ntest:], dst3_data[-Ntest:], 3)
+ self.assertComplexTuplesAlmostEqual(expected4_data[-Ntest:], dst4_data[-Ntest:], 3)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_pfb_channelizer, "test_pfb_channelizer.xml")
diff --git a/gr-filter/python/qa_pfb_decimator.py b/gr-filter/python/qa_pfb_decimator.py
new file mode 100755
index 0000000000..063845f638
--- /dev/null
+++ b/gr-filter/python/qa_pfb_decimator.py
@@ -0,0 +1,125 @@
+#!/usr/bin/env python
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import filter_swig as filter
+import math
+
+class test_pfb_decimator(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_000(self):
+ N = 1000 # number of samples to use
+ M = 5 # Number of channels
+ fs = 1000 # baseband sampling rate
+ ifs = M*fs # input samp rate to decimator
+ channel = 0 # Extract channel 0
+
+ taps = filter.firdes.low_pass_2(1, ifs, fs/2, fs/10,
+ attenuation_dB=80,
+ window=filter.firdes.WIN_BLACKMAN_hARRIS)
+
+ signals = list()
+ add = gr.add_cc()
+ freqs = [-200, -100, 0, 100, 200]
+ for i in xrange(len(freqs)):
+ f = freqs[i] + (M/2-M+i+1)*fs
+ signals.append(gr.sig_source_c(ifs, gr.GR_SIN_WAVE, f, 1))
+ self.tb.connect(signals[i], (add,i))
+
+ head = gr.head(gr.sizeof_gr_complex, N)
+ s2ss = gr.stream_to_streams(gr.sizeof_gr_complex, M)
+ pfb = filter.pfb_decimator_ccf(M, taps, channel)
+ snk = gr.vector_sink_c()
+
+ self.tb.connect(add, head, s2ss)
+ for i in xrange(M):
+ self.tb.connect((s2ss,i), (pfb,i))
+ self.tb.connect(pfb, snk)
+
+ self.tb.run()
+
+ Ntest = 50
+ L = len(snk.data())
+ t = map(lambda x: float(x)/fs, xrange(L))
+
+ # Create known data as complex sinusoids for the baseband freq
+ # of the extracted channel is due to decimator output order.
+ phase = 0
+ expected_data = map(lambda x: math.cos(2.*math.pi*freqs[2]*x+phase) + \
+ 1j*math.sin(2.*math.pi*freqs[2]*x+phase), t)
+
+ dst_data = snk.data()
+
+ self.assertComplexTuplesAlmostEqual(expected_data[-Ntest:], dst_data[-Ntest:], 4)
+
+ def test_001(self):
+ N = 1000 # number of samples to use
+ M = 5 # Number of channels
+ fs = 1000 # baseband sampling rate
+ ifs = M*fs # input samp rate to decimator
+ channel = 1 # Extract channel 0
+
+ taps = filter.firdes.low_pass_2(1, ifs, fs/2, fs/10,
+ attenuation_dB=80,
+ window=filter.firdes.WIN_BLACKMAN_hARRIS)
+
+ signals = list()
+ add = gr.add_cc()
+ freqs = [-200, -100, 0, 100, 200]
+ for i in xrange(len(freqs)):
+ f = freqs[i] + (M/2-M+i+1)*fs
+ signals.append(gr.sig_source_c(ifs, gr.GR_SIN_WAVE, f, 1))
+ self.tb.connect(signals[i], (add,i))
+
+ head = gr.head(gr.sizeof_gr_complex, N)
+ s2ss = gr.stream_to_streams(gr.sizeof_gr_complex, M)
+ pfb = filter.pfb_decimator_ccf(M, taps, channel)
+ snk = gr.vector_sink_c()
+
+ self.tb.connect(add, head, s2ss)
+ for i in xrange(M):
+ self.tb.connect((s2ss,i), (pfb,i))
+ self.tb.connect(pfb, snk)
+
+ self.tb.run()
+
+ Ntest = 50
+ L = len(snk.data())
+ t = map(lambda x: float(x)/fs, xrange(L))
+
+ # Create known data as complex sinusoids for the baseband freq
+ # of the extracted channel is due to decimator output order.
+ phase = 6.15746
+ expected_data = map(lambda x: math.cos(2.*math.pi*freqs[3]*x+phase) + \
+ 1j*math.sin(2.*math.pi*freqs[3]*x+phase), t)
+ dst_data = snk.data()
+
+ self.assertComplexTuplesAlmostEqual(expected_data[-Ntest:], dst_data[-Ntest:], 4)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_pfb_decimator, "test_pfb_decimator.xml")
diff --git a/gr-filter/python/qa_pfb_interpolator.py b/gr-filter/python/qa_pfb_interpolator.py
new file mode 100755
index 0000000000..5b84b7c642
--- /dev/null
+++ b/gr-filter/python/qa_pfb_interpolator.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import filter_swig as filter
+import math
+
+class test_pfb_interpolator(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_000(self):
+ N = 1000 # number of samples to use
+ M = 5 # Number of channels
+ fs = 1000 # baseband sampling rate
+ ifs = M*fs # input samp rate to decimator
+
+ taps = filter.firdes.low_pass_2(M, ifs, fs/2, fs/10,
+ attenuation_dB=80,
+ window=filter.firdes.WIN_BLACKMAN_hARRIS)
+
+ freq = 100
+ signal = gr.sig_source_c(fs, gr.GR_COS_WAVE, freq, 1)
+ head = gr.head(gr.sizeof_gr_complex, N)
+ pfb = filter.pfb_interpolator_ccf(M, taps)
+ snk = gr.vector_sink_c()
+
+ self.tb.connect(signal, head, pfb)
+ self.tb.connect(pfb, snk)
+
+ self.tb.run()
+
+ Ntest = 50
+ L = len(snk.data())
+ t = map(lambda x: float(x)/ifs, xrange(L))
+
+ # Create known data as complex sinusoids at freq
+ # of the channel at the interpolated rate.
+ phase = 0.62833
+ expected_data = map(lambda x: math.cos(2.*math.pi*freq*x+phase) + \
+ 1j*math.sin(2.*math.pi*freq*x+phase), t)
+
+ dst_data = snk.data()
+
+ self.assertComplexTuplesAlmostEqual(expected_data[-Ntest:], dst_data[-Ntest:], 4)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_pfb_interpolator, "test_pfb_interpolator.xml")
diff --git a/gr-filter/python/qa_pfb_synthesizer.py b/gr-filter/python/qa_pfb_synthesizer.py
new file mode 100755
index 0000000000..e8164d2683
--- /dev/null
+++ b/gr-filter/python/qa_pfb_synthesizer.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import filter_swig as filter
+import math
+
+class test_pfb_synthesizer(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_000(self):
+ N = 10000 # number of samples to use
+ M = 5 # Number of channels
+ fs = 1000 # baseband sampling rate
+ ofs = M*fs # input samp rate to decimator
+
+ taps = filter.firdes.low_pass_2(M, ofs, fs/2, fs/10,
+ attenuation_dB=80,
+ window=filter.firdes.WIN_BLACKMAN_hARRIS)
+
+ signals = list()
+ freqs = [0, 100, 200, -200, -100]
+ for i in xrange(len(freqs)):
+ signals.append(gr.sig_source_c(fs, gr.GR_SIN_WAVE, freqs[i], 1))
+
+ head = gr.head(gr.sizeof_gr_complex, N)
+ pfb = filter.pfb_synthesizer_ccf(M, taps)
+ snk = gr.vector_sink_c()
+
+ for i in xrange(M):
+ self.tb.connect(signals[i], (pfb,i))
+
+ self.tb.connect(pfb, head, snk)
+
+ self.tb.run()
+
+ Ntest = 1000
+ L = len(snk.data())
+ t = map(lambda x: float(x)/ofs, xrange(L))
+
+ # Create known data as sum of complex sinusoids at freqs
+ # of the output channels.
+ freqs = [-2200, -1100, 0, 1100, 2200]
+ expected_data = len(t)*[0,]
+ for i in xrange(len(t)):
+ expected_data[i] = math.cos(2.*math.pi*freqs[0]*t[i]) + \
+ 1j*math.sin(2.*math.pi*freqs[0]*t[i]) + \
+ math.cos(2.*math.pi*freqs[1]*t[i]) + \
+ 1j*math.sin(2.*math.pi*freqs[1]*t[i]) + \
+ math.cos(2.*math.pi*freqs[2]*t[i]) + \
+ 1j*math.sin(2.*math.pi*freqs[2]*t[i]) + \
+ math.cos(2.*math.pi*freqs[3]*t[i]) + \
+ 1j*math.sin(2.*math.pi*freqs[3]*t[i]) + \
+ math.cos(2.*math.pi*freqs[4]*t[i]) + \
+ 1j*math.sin(2.*math.pi*freqs[4]*t[i])
+ dst_data = snk.data()
+
+ offset = 25
+ self.assertComplexTuplesAlmostEqual(expected_data[2000-offset:2000-offset+Ntest],
+ dst_data[2000:2000+Ntest], 4)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_pfb_synthesizer, "test_pfb_synthesizer.xml")
diff --git a/gr-filter/python/qa_pm_remez.py b/gr-filter/python/qa_pm_remez.py
new file mode 100755
index 0000000000..a76e14c938
--- /dev/null
+++ b/gr-filter/python/qa_pm_remez.py
@@ -0,0 +1,188 @@
+#!/usr/bin/env python
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import filter_swig as filter
+import sys, math
+
+# ----------------------------------------------------------------
+# See optfir for an explanation of these.
+
+def stopband_atten_to_dev (atten_db):
+ """Convert a stopband attenuation in dB to an absolute value"""
+ return 10**(-atten_db/20)
+
+def passband_ripple_to_dev (ripple_db):
+ """Convert passband ripple spec expressed in dB to an absolute value"""
+ return (10**(ripple_db/20)-1)/(10**(ripple_db/20)+1)
+
+# ----------------------------------------------------------------
+
+def remezord (fcuts, mags, devs, fsamp = 2):
+ '''
+ FIR order estimator (lowpass, highpass, bandpass, mulitiband).
+ '''
+
+ # get local copies
+ fcuts = fcuts[:]
+ mags = mags[:]
+ devs = devs[:]
+
+ for i in range (len (fcuts)):
+ fcuts[i] = float (fcuts[i]) / fsamp
+
+ nf = len (fcuts)
+ nm = len (mags)
+ nd = len (devs)
+ nbands = nm
+
+ if nm != nd:
+ raise ValueError, "Length of mags and devs must be equal"
+
+ if nf != 2 * (nbands - 1):
+ raise ValueError, "Length of f must be 2 * len (mags) - 2"
+
+ for i in range (len (mags)):
+ if mags[i] != 0: # if not stopband, get relative deviation
+ devs[i] = devs[i] / mags[i]
+
+ # separate the passband and stopband edges
+ f1 = fcuts[0::2]
+ f2 = fcuts[1::2]
+
+ n = 0
+ min_delta = 2
+ for i in range (len (f1)):
+ if f2[i] - f1[i] < min_delta:
+ n = i
+ min_delta = f2[i] - f1[i]
+
+ if nbands == 2:
+ # lowpass or highpass case (use formula)
+ l = lporder (f1[n], f2[n], devs[0], devs[1])
+ else:
+ # bandpass or multipass case
+ # try different lowpasses and take the worst one that
+ # goes through the BP specs
+ l = 0
+ for i in range (1, nbands-1):
+ l1 = lporder (f1[i-1], f2[i-1], devs[i], devs[i-1])
+ l2 = lporder (f1[i], f2[i], devs[i], devs[i+1])
+ l = max (l, l1, l2)
+
+ n = int (math.ceil (l)) - 1 # need order, not length for remez
+
+ # cook up remez compatible result
+ ff = [0] + fcuts + [1]
+ for i in range (1, len (ff) - 1):
+ ff[i] *= 2
+
+ aa = []
+ for a in mags:
+ aa = aa + [a, a]
+
+ max_dev = max (devs)
+ wts = [1] * len(devs)
+ for i in range (len (wts)):
+ wts[i] = max_dev / devs[i]
+
+ return (n, ff, aa, wts)
+
+
+def lporder (freq1, freq2, delta_p, delta_s):
+ '''
+ FIR lowpass filter length estimator.
+ '''
+ df = abs (freq2 - freq1)
+ ddp = math.log10 (delta_p)
+ dds = math.log10 (delta_s)
+
+ a1 = 5.309e-3
+ a2 = 7.114e-2
+ a3 = -4.761e-1
+ a4 = -2.66e-3
+ a5 = -5.941e-1
+ a6 = -4.278e-1
+
+ b1 = 11.01217
+ b2 = 0.5124401
+
+ t1 = a1 * ddp * ddp
+ t2 = a2 * ddp
+ t3 = a4 * ddp * ddp
+ t4 = a5 * ddp
+
+ dinf=((t1 + t2 + a3) * dds) + (t3 + t4 + a6)
+ ff = b1 + b2 * (ddp - dds)
+ n = dinf / df - ff * df + 1
+ return n
+
+# ----------------------------------------------------------------
+
+class test_pm_remez(gr_unittest.TestCase):
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_low_pass(self):
+ gain = 1
+ Fs = 1
+ freq1 = 0.1
+ freq2 = 0.2
+ passband_ripple_db = 0.01
+ stopband_atten_db = 60
+
+ passband_dev = passband_ripple_to_dev(passband_ripple_db)
+ stopband_dev = stopband_atten_to_dev(stopband_atten_db)
+ desired_ampls = (gain, 0)
+ (n, fo, ao, w) = remezord([freq1, freq2], desired_ampls,
+ [passband_dev, stopband_dev], Fs)
+ new_taps = filter.pm_remez(n + 2, fo, ao, w, "bandpass")
+
+ known_taps = (-0.0008370135734511828, -0.0006622211673134374,
+ 0.0008501079576365787, 0.003059609130249229,
+ 0.003202235537205373, -0.001000899296974219,
+ -0.007589728680590891, -0.009790921118281865,
+ -0.001524210202628562, 0.014373535837200111,
+ 0.02392881326993834, 0.011798133085019008,
+ -0.021954446348997188, -0.05293436740264934,
+ -0.04375787096766848, 0.028038890498420392,
+ 0.14612655590172896, 0.25738578419108626,
+ 0.302967004188747, 0.25738578419108626,
+ 0.14612655590172896, 0.028038890498420392,
+ -0.04375787096766848, -0.05293436740264934,
+ -0.021954446348997188, 0.011798133085019008,
+ 0.02392881326993834, 0.014373535837200111,
+ -0.001524210202628562, -0.009790921118281865,
+ -0.007589728680590891, -0.001000899296974219,
+ 0.003202235537205373, 0.003059609130249229,
+ 0.0008501079576365787, -0.0006622211673134374,
+ -0.0008370135734511828)
+
+ self.assertFloatTuplesAlmostEqual(known_taps, new_taps, 5)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_pm_remez, "test_pm_remez.xml")
+
diff --git a/gr-filter/python/qa_rational_resampler.py b/gr-filter/python/qa_rational_resampler.py
new file mode 100755
index 0000000000..eb86ef5425
--- /dev/null
+++ b/gr-filter/python/qa_rational_resampler.py
@@ -0,0 +1,257 @@
+#!/usr/bin/env python
+#
+# Copyright 2005,2006,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import filter_swig as filter
+import math
+import random
+import sys
+
+
+def random_floats(n):
+ r = []
+ for x in xrange(n):
+ # r.append(float(random.randint(-32768, 32768)))
+ r.append(float(random.random()))
+ return tuple(r)
+
+
+def reference_dec_filter(src_data, decim, taps):
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = filter.fir_filter_fff(decim, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+ tb = None
+ return result_data
+
+def reference_interp_filter(src_data, interp, taps):
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = filter.interp_fir_filter_fff(interp, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+ tb = None
+ return result_data
+
+def reference_interp_dec_filter(src_data, interp, decim, taps):
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ up = filter.interp_fir_filter_fff(interp, (1,))
+ dn = filter.fir_filter_fff(decim, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, up, dn, dst)
+ tb.run()
+ result_data = dst.data()
+ tb = None
+ return result_data
+
+
+class test_rational_resampler (gr_unittest.TestCase):
+
+ def setUp(self):
+ random.seed(0)
+
+ def tearDown(self):
+ pass
+
+
+ def test_000_1_to_1(self):
+ taps = (-4, 5)
+ src_data = (234, -4, 23, -56, 45, 98, -23, -7)
+ xr = (1186, -112, 339, -460, -167, 582)
+ expected_result = tuple([float(x) for x in xr])
+
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = filter.rational_resampler_base_fff(1, 1, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op)
+ tb.connect(op, dst)
+ tb.run()
+ result_data = dst.data()
+ self.assertEqual(expected_result, result_data)
+
+ def test_001_interp(self):
+ taps = [1, 10, 100, 1000, 10000]
+ src_data = (0, 2, 3, 5, 7, 11, 13, 17)
+ interpolation = 3
+ xr = (0,2,20,200,2003,20030,
+ 300,3005,30050,
+ 500,5007,50070,
+ 700,7011,70110,
+ 1100,11013,110130,
+ 1300,13017,130170,
+ 1700.0,17000.0,170000.0)
+ expected_result = tuple([float(x) for x in xr])
+
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = filter.rational_resampler_base_fff(interpolation, 1, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op)
+ tb.connect(op, dst)
+ tb.run()
+ result_data = dst.data()
+ self.assertEqual(expected_result, result_data)
+
+ def test_002_interp(self):
+ taps = random_floats(31)
+ src_data = random_floats(10000)
+ interpolation = 3
+
+ expected_result = reference_interp_filter(src_data, interpolation, taps)
+
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = filter.rational_resampler_base_fff(interpolation, 1, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op)
+ tb.connect(op, dst)
+ tb.run()
+ result_data = dst.data()
+
+ N = 1000
+ offset = len(taps)-1
+ self.assertEqual(expected_result[offset:offset+N], result_data[0:N])
+
+ def xtest_003_interp(self):
+ taps = random_floats(9)
+ src_data = random_floats(10000)
+ decimation = 3
+
+ expected_result = reference_dec_filter(src_data, decimation, taps)
+
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = filter.rational_resampler_base_fff(1, decimation, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op)
+ tb.connect(op, dst)
+ tb.run()
+ result_data = dst.data()
+
+ N = 10
+ offset = 10#len(taps)-1
+ print expected_result[100+offset:100+offset+N]
+ print result_data[100:100+N]
+ #self.assertEqual(expected_result[offset:offset+N], result_data[0:N])
+
+ # FIXME disabled. Triggers hang on SuSE 10.0
+ def xtest_004_decim_random_vals(self):
+ MAX_TAPS = 9
+ MAX_DECIM = 7
+ OUTPUT_LEN = 9
+
+ random.seed(0) # we want reproducibility
+
+ for ntaps in xrange(1, MAX_TAPS + 1):
+ for decim in xrange(1, MAX_DECIM+1):
+ for ilen in xrange(ntaps + decim, ntaps + OUTPUT_LEN*decim):
+ src_data = random_floats(ilen)
+ taps = random_floats(ntaps)
+ expected_result = reference_dec_filter(src_data, decim, taps)
+
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = filter.rational_resampler_base_fff(1, decim, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op, dst)
+ tb.run()
+ tb = None
+ result_data = dst.data()
+
+ L1 = len(result_data)
+ L2 = len(expected_result)
+ L = min(L1, L2)
+ if False:
+ sys.stderr.write('delta = %2d: ntaps = %d decim = %d ilen = %d\n' % (L2 - L1, ntaps, decim, ilen))
+ sys.stderr.write(' len(result_data) = %d len(expected_result) = %d\n' %
+ (len(result_data), len(expected_result)))
+ self.assertEqual(expected_result[0:L], result_data[0:L])
+
+
+ # FIXME disabled. Triggers hang on SuSE 10.0
+ def xtest_005_interp_random_vals(self):
+ MAX_TAPS = 9
+ MAX_INTERP = 7
+ INPUT_LEN = 9
+
+ random.seed(0) # we want reproducibility
+
+ for ntaps in xrange(1, MAX_TAPS + 1):
+ for interp in xrange(1, MAX_INTERP+1):
+ for ilen in xrange(ntaps, ntaps + INPUT_LEN):
+ src_data = random_floats(ilen)
+ taps = random_floats(ntaps)
+ expected_result = reference_interp_filter(src_data, interp, taps)
+
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = filter.rational_resampler_base_fff(interp, 1, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op, dst)
+ tb.run()
+ tb = None
+ result_data = dst.data()
+ L1 = len(result_data)
+ L2 = len(expected_result)
+ L = min(L1, L2)
+ #if True or abs(L1-L2) > 1:
+ if False:
+ sys.stderr.write('delta = %2d: ntaps = %d interp = %d ilen = %d\n' % (L2 - L1, ntaps, interp, ilen))
+ #sys.stderr.write(' len(result_data) = %d len(expected_result) = %d\n' %
+ # (len(result_data), len(expected_result)))
+ #self.assertEqual(expected_result[0:L], result_data[0:L])
+ # FIXME check first ntaps+1 answers
+ self.assertEqual(expected_result[ntaps+1:L], result_data[ntaps+1:L])
+
+ def test_006_interp_decim(self):
+ taps = random_floats(31)
+ src_data = random_floats(10000)
+ interp = 3
+ decimation = 2
+
+ expected_result = reference_interp_dec_filter(src_data, interp, decimation, taps)
+
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = filter.rational_resampler_base_fff(interp, decimation, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op)
+ tb.connect(op, dst)
+ tb.run()
+ result_data = dst.data()
+
+ N = 1000
+ offset = len(taps)/2
+ self.assertFloatTuplesAlmostEqual(expected_result[offset:offset+N], result_data[0:N], 5)
+
+
+if __name__ == '__main__':
+ # FIXME: Disabled, see ticket:210
+ gr_unittest.run(test_rational_resampler, "test_rational_resampler.xml")
+
diff --git a/gr-filter/python/qa_single_pole_iir.py b/gr-filter/python/qa_single_pole_iir.py
new file mode 100755
index 0000000000..3608c77f95
--- /dev/null
+++ b/gr-filter/python/qa_single_pole_iir.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+#
+# Copyright 2005,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import filter_swig as filter
+
+class test_single_pole_iir_filter(gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_ff_001(self):
+ src_data = (0, 1000, 2000, 3000, 4000, 5000)
+ expected_result = src_data
+ src = gr.vector_source_f(src_data)
+ op = filter.single_pole_iir_filter_ff(1.0)
+ dst = gr.vector_sink_f()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertFloatTuplesAlmostEqual(expected_result, result_data)
+
+ def test_ff_002(self):
+ src_data = (0, 1000, 2000, 3000, 4000, 5000)
+ expected_result = (0, 125, 359.375, 689.453125, 1103.271484, 1590.36255)
+ src = gr.vector_source_f(src_data)
+ op = filter.single_pole_iir_filter_ff(0.125)
+ dst = gr.vector_sink_f()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertFloatTuplesAlmostEqual(expected_result, result_data, 3)
+
+ def test_ff_003(self):
+ block_size = 2
+ src_data = (0, 1000, 2000, 3000, 4000, 5000)
+ expected_result = (0, 125, 250, 484.375, 718.75, 1048.828125)
+ src = gr.vector_source_f(src_data)
+ s2p = gr.serial_to_parallel(gr.sizeof_float, block_size)
+ op = filter.single_pole_iir_filter_ff (0.125, block_size)
+ p2s = gr.parallel_to_serial(gr.sizeof_float, block_size)
+ dst = gr.vector_sink_f()
+ self.tb.connect(src, s2p, op, p2s, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertFloatTuplesAlmostEqual(expected_result, result_data, 3)
+
+ def test_cc_001(self):
+ src_data = (0+0j, 1000+1000j, 2000+2000j, 3000+3000j, 4000+4000j, 5000+5000j)
+ expected_result = src_data
+ src = gr.vector_source_c(src_data)
+ op = filter.single_pole_iir_filter_cc(1.0)
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_result, result_data)
+
+ def test_cc_002(self):
+ src_data = (complex(0,0), complex(1000,-1000), complex(2000,-2000),
+ complex(3000,-3000), complex(4000,-4000), complex(5000,-5000))
+ expected_result = (complex(0,0), complex(125,-125), complex(359.375,-359.375),
+ complex(689.453125,-689.453125), complex(1103.271484,-1103.271484),
+ complex(1590.36255,-1590.36255))
+ src = gr.vector_source_c(src_data)
+ op = filter.single_pole_iir_filter_cc(0.125)
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_result, result_data, 3)
+
+ def test_cc_003(self):
+ block_size = 2
+ src_data = (complex(0,0), complex(1000,-1000), complex(2000,-2000),
+ complex(3000,-3000), complex(4000,-4000), complex(5000,-5000))
+ expected_result = (complex(0,0), complex(125,-125), complex(250,-250),
+ complex(484.375,-484.375), complex(718.75,-718.75),
+ complex(1048.828125,-1048.828125))
+ src = gr.vector_source_c(src_data)
+ s2p = gr.serial_to_parallel(gr.sizeof_gr_complex, block_size)
+ op = filter.single_pole_iir_filter_cc(0.125, block_size)
+ p2s = gr.parallel_to_serial(gr.sizeof_gr_complex, block_size)
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, s2p, op, p2s, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual(expected_result, result_data, 3)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_single_pole_iir_filter, "test_single_pole_iir_filter.xml")
+
diff --git a/gr-filter/python/rational_resampler.py b/gr-filter/python/rational_resampler.py
new file mode 100644
index 0000000000..312b011d32
--- /dev/null
+++ b/gr-filter/python/rational_resampler.py
@@ -0,0 +1,129 @@
+#
+# Copyright 2005,2007 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gru
+
+_plot = None
+
+def design_filter(interpolation, decimation, fractional_bw):
+ """
+ Given the interpolation rate, decimation rate and a fractional bandwidth,
+ design a set of taps.
+
+ @param interpolation: interpolation factor
+ @type interpolation: integer > 0
+ @param decimation: decimation factor
+ @type decimation: integer > 0
+ @param fractional_bw: fractional bandwidth in (0, 0.5) 0.4 works well.
+ @type fractional_bw: float
+ @returns: sequence of numbers
+ """
+
+ if fractional_bw >= 0.5 or fractional_bw <= 0:
+ raise ValueError, "Invalid fractional_bandwidth, must be in (0, 0.5)"
+
+ beta = 5.0
+ trans_width = 0.5 - fractional_bw
+ mid_transition_band = 0.5 - trans_width/2
+
+ taps = filter.firdes.low_pass(interpolation, # gain
+ 1, # Fs
+ mid_transition_band/interpolation, # trans mid point
+ trans_width/interpolation, # transition width
+ filter.firdes.WIN_KAISER,
+ beta) # beta
+ return taps
+
+
+
+class _rational_resampler_base(gr.hier_block2):
+ """
+ base class for all rational resampler variants.
+ """
+ def __init__(self, resampler_base,
+ interpolation, decimation, taps=None, fractional_bw=None):
+ """
+ Rational resampling polyphase FIR filter.
+
+ Either taps or fractional_bw may be specified, but not both.
+ If neither is specified, a reasonable default, 0.4, is used as
+ the fractional_bw.
+
+ @param interpolation: interpolation factor
+ @type interpolation: integer > 0
+ @param decimation: decimation factor
+ @type decimation: integer > 0
+ @param taps: optional filter coefficients
+ @type taps: sequence
+ @param fractional_bw: fractional bandwidth in (0, 0.5), measured at final freq (use 0.4)
+ @type fractional_bw: float
+ """
+
+ if not isinstance(interpolation, int) or interpolation < 1:
+ raise ValueError, "interpolation must be an integer >= 1"
+
+ if not isinstance(decimation, int) or decimation < 1:
+ raise ValueError, "decimation must be an integer >= 1"
+
+ if taps is None and fractional_bw is None:
+ fractional_bw = 0.4
+
+ d = gru.gcd(interpolation, decimation)
+ interpolation = interpolation // d
+ decimation = decimation // d
+
+ if taps is None:
+ taps = design_filter(interpolation, decimation, fractional_bw)
+
+ resampler = resampler_base(interpolation, decimation, taps)
+ gr.hier_block2.__init__(self, "rational_resampler",
+ gr.io_signature(1, 1, resampler.input_signature().sizeof_stream_item(0)),
+ gr.io_signature(1, 1, resampler.output_signature().sizeof_stream_item(0)))
+
+ self.connect(self, resampler, self)
+
+
+class rational_resampler_fff(_rational_resampler_base):
+ def __init__(self, interpolation, decimation, taps=None, fractional_bw=None):
+ """
+ Rational resampling polyphase FIR filter with
+ float input, float output and float taps.
+ """
+ _rational_resampler_base.__init__(self, filter.rational_resampler_base_fff,
+ interpolation, decimation, taps, fractional_bw)
+
+class rational_resampler_ccf(_rational_resampler_base):
+ def __init__(self, interpolation, decimation, taps=None, fractional_bw=None):
+ """
+ Rational resampling polyphase FIR filter with
+ complex input, complex output and float taps.
+ """
+ _rational_resampler_base.__init__(self, filter.rational_resampler_base_ccf,
+ interpolation, decimation, taps, fractional_bw)
+
+class rational_resampler_ccc(_rational_resampler_base):
+ def __init__(self, interpolation, decimation, taps=None, fractional_bw=None):
+ """
+ Rational resampling polyphase FIR filter with
+ complex input, complex output and complex taps.
+ """
+ _rational_resampler_base.__init__(self, filter.rational_resampler_base_ccc,
+ interpolation, decimation, taps, fractional_bw)
diff --git a/gr-filter/swig/CMakeLists.txt b/gr-filter/swig/CMakeLists.txt
new file mode 100644
index 0000000000..3eee3a1ee4
--- /dev/null
+++ b/gr-filter/swig/CMakeLists.txt
@@ -0,0 +1,53 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+# Setup swig generation
+########################################################################
+include(GrPython)
+include(GrSwig)
+
+set(GR_SWIG_INCLUDE_DIRS
+ ${GR_FILTER_INCLUDE_DIRS}
+ ${GNURADIO_CORE_SWIG_INCLUDE_DIRS}
+ ${FFT_INCLUDE_DIRS}
+ ${FFTW3F_INCLUDE_DIRS}
+)
+
+# FIXME: rename to filter_swig_doc.i when gnuradio-core is updated
+set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/gr_filter_swig_doc.i)
+set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../lib)
+
+set(GR_SWIG_LIBRARIES gnuradio-filter gnuradio-fft)
+
+GR_SWIG_MAKE(filter_swig filter_swig.i)
+
+GR_SWIG_INSTALL(
+ TARGETS filter_swig
+ DESTINATION ${GR_PYTHON_DIR}/gnuradio/filter
+ COMPONENT "filter_python"
+)
+
+install(
+ FILES
+ filter_swig.i
+ ${CMAKE_CURRENT_BINARY_DIR}/gr_filter_swig_doc.i
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio/swig
+ COMPONENT "filter_swig"
+)
diff --git a/gr-filter/swig/filter_swig.i b/gr-filter/swig/filter_swig.i
new file mode 100644
index 0000000000..05b84d4d69
--- /dev/null
+++ b/gr-filter/swig/filter_swig.i
@@ -0,0 +1,169 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#define FILTER_API
+
+%include "gnuradio.i"
+
+//load generated python docstrings
+%include "gr_filter_swig_doc.i"
+
+%{
+#include "filter/firdes.h"
+#include "filter/pm_remez.h"
+#include "filter/adaptive_fir_ccc.h"
+#include "filter/adaptive_fir_ccf.h"
+#include "filter/dc_blocker_cc.h"
+#include "filter/dc_blocker_ff.h"
+#include "filter/filter_delay_fc.h"
+#include "filter/fir_filter_ccc.h"
+#include "filter/fir_filter_ccf.h"
+#include "filter/fir_filter_fcc.h"
+#include "filter/fir_filter_fff.h"
+#include "filter/fir_filter_fsf.h"
+#include "filter/fir_filter_scc.h"
+#include "filter/fft_filter_ccc.h"
+#include "filter/fft_filter_fff.h"
+#include "filter/fractional_interpolator_cc.h"
+#include "filter/fractional_interpolator_ff.h"
+#include "filter/freq_xlating_fir_filter_ccc.h"
+#include "filter/freq_xlating_fir_filter_ccf.h"
+#include "filter/freq_xlating_fir_filter_fcc.h"
+#include "filter/freq_xlating_fir_filter_fcf.h"
+#include "filter/freq_xlating_fir_filter_scf.h"
+#include "filter/freq_xlating_fir_filter_scc.h"
+#include "filter/hilbert_fc.h"
+#include "filter/iir_filter_ffd.h"
+#include "filter/interp_fir_filter_ccc.h"
+#include "filter/interp_fir_filter_ccf.h"
+#include "filter/interp_fir_filter_fcc.h"
+#include "filter/interp_fir_filter_fff.h"
+#include "filter/interp_fir_filter_fsf.h"
+#include "filter/interp_fir_filter_scc.h"
+#include "filter/pfb_arb_resampler_ccf.h"
+#include "filter/pfb_arb_resampler_fff.h"
+#include "filter/pfb_channelizer_ccf.h"
+#include "filter/pfb_decimator_ccf.h"
+#include "filter/pfb_interpolator_ccf.h"
+#include "filter/pfb_synthesizer_ccf.h"
+#include "filter/rational_resampler_base_ccc.h"
+#include "filter/rational_resampler_base_ccf.h"
+#include "filter/rational_resampler_base_fcc.h"
+#include "filter/rational_resampler_base_fff.h"
+#include "filter/rational_resampler_base_fsf.h"
+#include "filter/rational_resampler_base_scc.h"
+#include "filter/single_pole_iir_filter_cc.h"
+#include "filter/single_pole_iir_filter_ff.h"
+#include "filter/channel_model.h"
+%}
+
+%include "filter/firdes.h"
+%include "filter/pm_remez.h"
+%include "filter/adaptive_fir_ccc.h"
+%include "filter/adaptive_fir_ccf.h"
+%include "filter/dc_blocker_cc.h"
+%include "filter/dc_blocker_ff.h"
+%include "filter/filter_delay_fc.h"
+%include "filter/fir_filter_ccc.h"
+%include "filter/fir_filter_ccf.h"
+%include "filter/fir_filter_fcc.h"
+%include "filter/fir_filter_fff.h"
+%include "filter/fir_filter_fsf.h"
+%include "filter/fir_filter_scc.h"
+%include "filter/fft_filter_ccc.h"
+%include "filter/fft_filter_fff.h"
+%include "filter/fractional_interpolator_cc.h"
+%include "filter/fractional_interpolator_ff.h"
+%include "filter/freq_xlating_fir_filter_ccc.h"
+%include "filter/freq_xlating_fir_filter_ccf.h"
+%include "filter/freq_xlating_fir_filter_fcc.h"
+%include "filter/freq_xlating_fir_filter_fcf.h"
+%include "filter/freq_xlating_fir_filter_scf.h"
+%include "filter/freq_xlating_fir_filter_scc.h"
+%include "filter/hilbert_fc.h"
+%include "filter/iir_filter_ffd.h"
+%include "filter/interp_fir_filter_ccc.h"
+%include "filter/interp_fir_filter_ccf.h"
+%include "filter/interp_fir_filter_fcc.h"
+%include "filter/interp_fir_filter_fff.h"
+%include "filter/interp_fir_filter_fsf.h"
+%include "filter/interp_fir_filter_scc.h"
+%include "filter/pfb_arb_resampler_ccf.h"
+%include "filter/pfb_arb_resampler_fff.h"
+%include "filter/pfb_channelizer_ccf.h"
+%include "filter/pfb_decimator_ccf.h"
+%include "filter/pfb_interpolator_ccf.h"
+%include "filter/pfb_synthesizer_ccf.h"
+%include "filter/rational_resampler_base_ccc.h"
+%include "filter/rational_resampler_base_ccf.h"
+%include "filter/rational_resampler_base_fcc.h"
+%include "filter/rational_resampler_base_fff.h"
+%include "filter/rational_resampler_base_fsf.h"
+%include "filter/rational_resampler_base_scc.h"
+%include "filter/single_pole_iir_filter_cc.h"
+%include "filter/single_pole_iir_filter_ff.h"
+%include "filter/channel_model.h"
+
+GR_SWIG_BLOCK_MAGIC2(filter, adaptive_fir_ccc);
+GR_SWIG_BLOCK_MAGIC2(filter, adaptive_fir_ccf);
+GR_SWIG_BLOCK_MAGIC2(filter, dc_blocker_cc);
+GR_SWIG_BLOCK_MAGIC2(filter, dc_blocker_ff);
+GR_SWIG_BLOCK_MAGIC2(filter, filter_delay_fc);
+GR_SWIG_BLOCK_MAGIC2(filter, fir_filter_ccc);
+GR_SWIG_BLOCK_MAGIC2(filter, fir_filter_ccf);
+GR_SWIG_BLOCK_MAGIC2(filter, fir_filter_fcc);
+GR_SWIG_BLOCK_MAGIC2(filter, fir_filter_fff);
+GR_SWIG_BLOCK_MAGIC2(filter, fir_filter_fsf);
+GR_SWIG_BLOCK_MAGIC2(filter, fir_filter_scc);
+GR_SWIG_BLOCK_MAGIC2(filter, fft_filter_ccc);
+GR_SWIG_BLOCK_MAGIC2(filter, fft_filter_fff);
+GR_SWIG_BLOCK_MAGIC2(filter, fractional_interpolator_cc);
+GR_SWIG_BLOCK_MAGIC2(filter, fractional_interpolator_ff);
+GR_SWIG_BLOCK_MAGIC2(filter, freq_xlating_fir_filter_ccc);
+GR_SWIG_BLOCK_MAGIC2(filter, freq_xlating_fir_filter_ccf);
+GR_SWIG_BLOCK_MAGIC2(filter, freq_xlating_fir_filter_fcc);
+GR_SWIG_BLOCK_MAGIC2(filter, freq_xlating_fir_filter_fcf);
+GR_SWIG_BLOCK_MAGIC2(filter, freq_xlating_fir_filter_scf);
+GR_SWIG_BLOCK_MAGIC2(filter, freq_xlating_fir_filter_scc);
+GR_SWIG_BLOCK_MAGIC2(filter, hilbert_fc);
+GR_SWIG_BLOCK_MAGIC2(filter, iir_filter_ffd);
+GR_SWIG_BLOCK_MAGIC2(filter, interp_fir_filter_ccc);
+GR_SWIG_BLOCK_MAGIC2(filter, interp_fir_filter_ccf);
+GR_SWIG_BLOCK_MAGIC2(filter, interp_fir_filter_fcc);
+GR_SWIG_BLOCK_MAGIC2(filter, interp_fir_filter_fff);
+GR_SWIG_BLOCK_MAGIC2(filter, interp_fir_filter_fsf);
+GR_SWIG_BLOCK_MAGIC2(filter, interp_fir_filter_scc);
+GR_SWIG_BLOCK_MAGIC2(filter, pfb_arb_resampler_ccf);
+GR_SWIG_BLOCK_MAGIC2(filter, pfb_arb_resampler_fff);
+GR_SWIG_BLOCK_MAGIC2(filter, pfb_channelizer_ccf);
+GR_SWIG_BLOCK_MAGIC2(filter, pfb_decimator_ccf);
+GR_SWIG_BLOCK_MAGIC2(filter, pfb_interpolator_ccf);
+GR_SWIG_BLOCK_MAGIC2(filter, pfb_synthesizer_ccf);
+GR_SWIG_BLOCK_MAGIC2(filter, rational_resampler_base_ccc);
+GR_SWIG_BLOCK_MAGIC2(filter, rational_resampler_base_ccf);
+GR_SWIG_BLOCK_MAGIC2(filter, rational_resampler_base_fcc);
+GR_SWIG_BLOCK_MAGIC2(filter, rational_resampler_base_fff);
+GR_SWIG_BLOCK_MAGIC2(filter, rational_resampler_base_fsf);
+GR_SWIG_BLOCK_MAGIC2(filter, rational_resampler_base_scc);
+GR_SWIG_BLOCK_MAGIC2(filter, single_pole_iir_filter_cc);
+GR_SWIG_BLOCK_MAGIC2(filter, single_pole_iir_filter_ff);
+GR_SWIG_BLOCK_MAGIC2(filter, channel_model);
diff --git a/gr-pager/apps/usrp_flex_all b/gr-pager/apps/usrp_flex_all
index 75c4c1e737..8ecf5a41ff 100755
--- a/gr-pager/apps/usrp_flex_all
+++ b/gr-pager/apps/usrp_flex_all
@@ -98,9 +98,9 @@ class app_top_block(gr.top_block):
mid_chan = int(self.nchan/2)
for i in range(self.nchan):
if i < mid_chan:
- freq = 930.5e6+i*25e3
+ freq = options.freq+i*25e3
else:
- freq = 930.5e6-(self.nchan-i)*25e3
+ freq = options.freq-(self.nchan-i)*25e3
if (freq < 929.0e6 or freq > 932.0e6):
self.connect((self.bank, i), gr.null_sink(gr.sizeof_gr_complex))
diff --git a/gr-trellis/doc/gr-trellis.xml b/gr-trellis/doc/gr-trellis.xml
index 4657dab384..58aa74d409 100644
--- a/gr-trellis/doc/gr-trellis.xml
+++ b/gr-trellis/doc/gr-trellis.xml
@@ -587,7 +587,7 @@ outputs a sequence of D numbers ci1,ci2,...,ciD representing the
coordianates of the constellation symbol c_i with i=y_k.
</para>
<programlisting>
- 20 mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
+ 20 mod = digital.chunks_to_symbols_sf(constellation,dimensionality)
</programlisting>
<para>
@@ -804,7 +804,7 @@ L being the channel length. This is sufficient to drive the initial and final st
23 packet[i] = 0
24 packet[len(packet)-i-1] = 0
25 src = gr.vector_source_s(packet,False)
- 26 mod = gr.chunks_to_symbols_sf(modulation[1],modulation[0])
+ 26 mod = digital.chunks_to_symbols_sf(modulation[1],modulation[0])
</programlisting>
diff --git a/gr-trellis/doc/test_tcm.py b/gr-trellis/doc/test_tcm.py
index 8c046d697b..3a285e27a2 100644
--- a/gr-trellis/doc/test_tcm.py
+++ b/gr-trellis/doc/test_tcm.py
@@ -17,7 +17,7 @@ def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
src_head = gr.head (gr.sizeof_short,Kb/16) # packet size in shorts
s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the FSM input cardinality
enc = trellis.encoder_ss(f,0) # initial state = 0
- mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
+ mod = digital.chunks_to_symbols_sf(constellation,dimensionality)
# CHANNEL
add = gr.add_ff()
diff --git a/gr-trellis/doc/test_tcm.py.xml b/gr-trellis/doc/test_tcm.py.xml
index b5074cb2f4..a4c541e38a 100644
--- a/gr-trellis/doc/test_tcm.py.xml
+++ b/gr-trellis/doc/test_tcm.py.xml
@@ -19,7 +19,7 @@
17 src_head = gr.head (gr.sizeof_short,Kb/16) # packet size in shorts
18 s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the FSM input cardinality
19 enc = trellis.encoder_ss(f,0) # initial state = 0
- 20 mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
+ 20 mod = digital.chunks_to_symbols_sf(constellation,dimensionality)
21
22 # CHANNEL
23 add = gr.add_ff()
diff --git a/gr-trellis/doc/test_viterbi_equalization1.py b/gr-trellis/doc/test_viterbi_equalization1.py
index 5967384cf9..c9c897fe2e 100755
--- a/gr-trellis/doc/test_viterbi_equalization1.py
+++ b/gr-trellis/doc/test_viterbi_equalization1.py
@@ -23,7 +23,7 @@ def run_test (f,Kb,bitspersymbol,K,channel,modulation,dimensionality,tot_constel
packet[i] = 0
packet[len(packet)-i-1] = 0
src = gr.vector_source_s(packet,False)
- mod = gr.chunks_to_symbols_sf(modulation[1],modulation[0])
+ mod = digital.chunks_to_symbols_sf(modulation[1],modulation[0])
# CHANNEL
isi = gr.fir_filter_fff(1,channel)
diff --git a/gr-trellis/doc/test_viterbi_equalization1.py.xml b/gr-trellis/doc/test_viterbi_equalization1.py.xml
index 27605870e8..751633a618 100644
--- a/gr-trellis/doc/test_viterbi_equalization1.py.xml
+++ b/gr-trellis/doc/test_viterbi_equalization1.py.xml
@@ -25,7 +25,7 @@
23 packet[i] = 0
24 packet[len(packet)-i-1] = 0
25 src = gr.vector_source_s(packet,False)
- 26 mod = gr.chunks_to_symbols_sf(modulation[1],modulation[0])
+ 26 mod = digital.chunks_to_symbols_sf(modulation[1],modulation[0])
27
28 # CHANNEL
29 isi = gr.fir_filter_fff(1,channel)
diff --git a/gr-trellis/src/examples/python/test_cpm.py b/gr-trellis/src/examples/python/test_cpm.py
index 5342e57e82..7503a458b1 100755
--- a/gr-trellis/src/examples/python/test_cpm.py
+++ b/gr-trellis/src/examples/python/test_cpm.py
@@ -89,7 +89,7 @@ def run_test(seed,blocksize):
# Blocks
##################################################
random_source_x_0 = gr.vector_source_b(data.tolist(), False)
- gr_chunks_to_symbols_xx_0 = gr.chunks_to_symbols_bf((-1, 1), 1)
+ digital_chunks_to_symbols_xx_0 = digital.chunks_to_symbols_bf((-1, 1), 1)
gr_interp_fir_filter_xxx_0 = gr.interp_fir_filter_fff(Q, p)
gr_frequency_modulator_fc_0 = gr.frequency_modulator_fc(2*math.pi*h*(1.0/Q))
@@ -111,8 +111,8 @@ def run_test(seed,blocksize):
##################################################
# Connections
##################################################
- tb.connect((random_source_x_0, 0), (gr_chunks_to_symbols_xx_0, 0))
- tb.connect((gr_chunks_to_symbols_xx_0, 0), (gr_interp_fir_filter_xxx_0, 0))
+ tb.connect((random_source_x_0, 0), (digital_chunks_to_symbols_xx_0, 0))
+ tb.connect((digital_chunks_to_symbols_xx_0, 0), (gr_interp_fir_filter_xxx_0, 0))
tb.connect((gr_interp_fir_filter_xxx_0, 0), (gr_frequency_modulator_fc_0, 0))
tb.connect((gr_frequency_modulator_fc_0, 0), (gr_add_vxx_0, 0))
tb.connect((gr_noise_source_x_0, 0), (gr_add_vxx_0, 1))
diff --git a/gr-trellis/src/examples/python/test_pccc_turbo1.py b/gr-trellis/src/examples/python/test_pccc_turbo1.py
index 0655b972de..abc0e1d01f 100755
--- a/gr-trellis/src/examples/python/test_pccc_turbo1.py
+++ b/gr-trellis/src/examples/python/test_pccc_turbo1.py
@@ -20,7 +20,7 @@ def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,
#src = gr.vector_source_s([0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1],False)
enc = trellis.pccc_encoder_ss(fo,0,fi,0,interleaver,K)
code = gr.vector_sink_s()
- mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
+ mod = digital.chunks_to_symbols_sf(constellation,dimensionality)
# CHANNEL
add = gr.add_ff()
diff --git a/gr-trellis/src/examples/python/test_sccc_hard.py b/gr-trellis/src/examples/python/test_sccc_hard.py
index 4eeb94a12d..397ebf0871 100755
--- a/gr-trellis/src/examples/python/test_sccc_hard.py
+++ b/gr-trellis/src/examples/python/test_sccc_hard.py
@@ -19,7 +19,7 @@ def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,
enc_out = trellis.encoder_ss(fo,0) # initial state = 0
inter = trellis.permutation(interleaver.K(),interleaver.INTER(),1,gr.sizeof_short)
enc_in = trellis.encoder_ss(fi,0) # initial state = 0
- mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
+ mod = digital.chunks_to_symbols_sf(constellation,dimensionality)
# CHANNEL
add = gr.add_ff()
diff --git a/gr-trellis/src/examples/python/test_sccc_soft.py b/gr-trellis/src/examples/python/test_sccc_soft.py
index 10c28419a8..b1ffaae748 100755
--- a/gr-trellis/src/examples/python/test_sccc_soft.py
+++ b/gr-trellis/src/examples/python/test_sccc_soft.py
@@ -22,7 +22,7 @@ def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,
enc_out = trellis.encoder_ss(fo,0) # initial state = 0
inter = trellis.permutation(interleaver.K(),interleaver.INTER(),1,gr.sizeof_short)
enc_in = trellis.encoder_ss(fi,0) # initial state = 0
- mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
+ mod = digital.chunks_to_symbols_sf(constellation,dimensionality)
# CHANNEL
add = gr.add_ff()
diff --git a/gr-trellis/src/examples/python/test_sccc_turbo.py b/gr-trellis/src/examples/python/test_sccc_turbo.py
index 762a93ba51..e8054a08b2 100755
--- a/gr-trellis/src/examples/python/test_sccc_turbo.py
+++ b/gr-trellis/src/examples/python/test_sccc_turbo.py
@@ -61,7 +61,7 @@ def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,
enc_out = trellis.encoder_ss(fo,0) # initial state = 0
inter = trellis.permutation(interleaver.K(),interleaver.INTER(),1,gr.sizeof_short)
enc_in = trellis.encoder_ss(fi,0) # initial state = 0
- mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
+ mod = digital.chunks_to_symbols_sf(constellation,dimensionality)
# CHANNEL
add = gr.add_ff()
diff --git a/gr-trellis/src/examples/python/test_sccc_turbo1.py b/gr-trellis/src/examples/python/test_sccc_turbo1.py
index 187a75185f..ef5d32f588 100755
--- a/gr-trellis/src/examples/python/test_sccc_turbo1.py
+++ b/gr-trellis/src/examples/python/test_sccc_turbo1.py
@@ -17,7 +17,7 @@ def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,
src_head = gr.head (gr.sizeof_short,Kb/16) # packet size in shorts
s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the outer FSM input cardinality
enc = trellis.sccc_encoder_ss(fo,0,fi,0,interleaver,K)
- mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
+ mod = digital.chunks_to_symbols_sf(constellation,dimensionality)
# CHANNEL
add = gr.add_ff()
diff --git a/gr-trellis/src/examples/python/test_sccc_turbo2.py b/gr-trellis/src/examples/python/test_sccc_turbo2.py
index dff1ba93c3..942572676d 100755
--- a/gr-trellis/src/examples/python/test_sccc_turbo2.py
+++ b/gr-trellis/src/examples/python/test_sccc_turbo2.py
@@ -17,7 +17,7 @@ def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,
src_head = gr.head (gr.sizeof_short,Kb/16) # packet size in shorts
s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the outer FSM input cardinality
enc = trellis.sccc_encoder_ss(fo,0,fi,0,interleaver,K)
- mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
+ mod = digital.chunks_to_symbols_sf(constellation,dimensionality)
# CHANNEL
add = gr.add_ff()
diff --git a/gr-trellis/src/examples/python/test_tcm.py b/gr-trellis/src/examples/python/test_tcm.py
index a7d6a02d04..eff93f5b4e 100755
--- a/gr-trellis/src/examples/python/test_tcm.py
+++ b/gr-trellis/src/examples/python/test_tcm.py
@@ -24,7 +24,7 @@ def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
#b2s = gr.unpacked_to_packed_ss(1,gr.GR_MSB_FIRST) # pack bits in shorts
s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the FSM input cardinality
enc = trellis.encoder_ss(f,0) # initial state = 0
- mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
+ mod = digital.chunks_to_symbols_sf(constellation,dimensionality)
# CHANNEL
add = gr.add_ff()
diff --git a/gr-trellis/src/examples/python/test_tcm_bit.py b/gr-trellis/src/examples/python/test_tcm_bit.py
index 7f69c0e294..1a89d06a89 100755
--- a/gr-trellis/src/examples/python/test_tcm_bit.py
+++ b/gr-trellis/src/examples/python/test_tcm_bit.py
@@ -25,7 +25,7 @@ def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
b2s = gr.unpacked_to_packed_ss(1,gr.GR_MSB_FIRST) # pack bits in shorts
s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the FSM input cardinality
enc = trellis.encoder_ss(f,0) # initial state = 0
- mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
+ mod = digital.chunks_to_symbols_sf(constellation,dimensionality)
# CHANNEL
diff --git a/gr-trellis/src/examples/python/test_tcm_combined.py b/gr-trellis/src/examples/python/test_tcm_combined.py
index d98e36e27d..a46444e32b 100755
--- a/gr-trellis/src/examples/python/test_tcm_combined.py
+++ b/gr-trellis/src/examples/python/test_tcm_combined.py
@@ -18,7 +18,7 @@ def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
src_head = gr.head (gr.sizeof_short,Kb/16) # packet size in shorts
s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the FSM input cardinality
enc = trellis.encoder_ss(f,0) # initial state = 0
- mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
+ mod = digital.chunks_to_symbols_sf(constellation,dimensionality)
# CHANNEL
diff --git a/gr-trellis/src/examples/python/test_tcm_parallel.py b/gr-trellis/src/examples/python/test_tcm_parallel.py
index 0372351aad..72fb8cf3bf 100755
--- a/gr-trellis/src/examples/python/test_tcm_parallel.py
+++ b/gr-trellis/src/examples/python/test_tcm_parallel.py
@@ -19,7 +19,7 @@ def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed,P):
s2fsmi=gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the FSM input cardinality
s2p = gr.stream_to_streams(gr.sizeof_short,P) # serial to parallel
enc = trellis.encoder_ss(f,0) # initiali state = 0
- mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
+ mod = digital.chunks_to_symbols_sf(constellation,dimensionality)
# CHANNEL
add=[]
diff --git a/gr-trellis/src/examples/python/test_turbo_equalization.py b/gr-trellis/src/examples/python/test_turbo_equalization.py
index 18bfb022a9..d97f3f2c29 100755
--- a/gr-trellis/src/examples/python/test_turbo_equalization.py
+++ b/gr-trellis/src/examples/python/test_turbo_equalization.py
@@ -59,7 +59,7 @@ def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,tot_constellat
inter = trellis.permutation(interleaver.K(),interleaver.INTER(),1,gr.sizeof_short)
enc_in = trellis.encoder_ss(fi,0) # initial state = 0
# essentially here we implement the combination of modulation and channel as a memoryless modulation (the memory induced by the channel is hidden in the innner FSM)
- mod = gr.chunks_to_symbols_sf(tot_constellation,dimensionality)
+ mod = digital.chunks_to_symbols_sf(tot_constellation,dimensionality)
# CHANNEL
add = gr.add_ff()
diff --git a/gr-trellis/src/examples/python/test_turbo_equalization1.py b/gr-trellis/src/examples/python/test_turbo_equalization1.py
index 17ad430235..da1132d38c 100755
--- a/gr-trellis/src/examples/python/test_turbo_equalization1.py
+++ b/gr-trellis/src/examples/python/test_turbo_equalization1.py
@@ -61,7 +61,7 @@ def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,channel,modulation,dimensiona
src = gr.vector_source_s(packet,False)
enc_out = trellis.encoder_ss(fo,0) # initial state = 0
inter = trellis.permutation(interleaver.K(),interleaver.INTER(),1,gr.sizeof_short)
- mod = gr.chunks_to_symbols_sf(modulation[1],modulation[0])
+ mod = digital.chunks_to_symbols_sf(modulation[1],modulation[0])
# CHANNEL
isi = gr.fir_filter_fff(1,channel)
diff --git a/gr-trellis/src/examples/python/test_turbo_equalization2.py b/gr-trellis/src/examples/python/test_turbo_equalization2.py
index 5a6c77e9d4..886240efac 100755
--- a/gr-trellis/src/examples/python/test_turbo_equalization2.py
+++ b/gr-trellis/src/examples/python/test_turbo_equalization2.py
@@ -59,7 +59,7 @@ def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,channel,modulation,dimensiona
src = gr.vector_source_s(packet,False)
enc_out = trellis.encoder_ss(fo,0) # initial state = 0
inter = trellis.permutation(interleaver.K(),interleaver.INTER(),1,gr.sizeof_short)
- mod = gr.chunks_to_symbols_sf(modulation[1],modulation[0])
+ mod = digital.chunks_to_symbols_sf(modulation[1],modulation[0])
# CHANNEL
isi = gr.fir_filter_fff(1,channel)
diff --git a/gr-trellis/src/examples/python/test_viterbi_equalization.py b/gr-trellis/src/examples/python/test_viterbi_equalization.py
index 9f3f7e3911..00d54620b2 100755
--- a/gr-trellis/src/examples/python/test_viterbi_equalization.py
+++ b/gr-trellis/src/examples/python/test_viterbi_equalization.py
@@ -16,7 +16,7 @@ def run_test (f,Kb,bitspersymbol,K,dimensionality,tot_constellation,N0,seed):
s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the FSM input cardinality
enc = trellis.encoder_ss(f,0) # initial state = 0
# essentially here we implement the combination of modulation and channel as a memoryless modulation (the memory induced by the channel is hidden in the FSM)
- mod = gr.chunks_to_symbols_sf(tot_constellation,dimensionality)
+ mod = digital.chunks_to_symbols_sf(tot_constellation,dimensionality)
# CHANNEL
add = gr.add_ff()
diff --git a/gr-trellis/src/examples/python/test_viterbi_equalization1.py b/gr-trellis/src/examples/python/test_viterbi_equalization1.py
index 90eb4790e5..caf99ff581 100755
--- a/gr-trellis/src/examples/python/test_viterbi_equalization1.py
+++ b/gr-trellis/src/examples/python/test_viterbi_equalization1.py
@@ -22,7 +22,7 @@ def run_test (f,Kb,bitspersymbol,K,channel,modulation,dimensionality,tot_constel
packet[i] = 0
packet[len(packet)-i-1] = 0
src = gr.vector_source_s(packet,False)
- mod = gr.chunks_to_symbols_sf(modulation[1],modulation[0])
+ mod = digital.chunks_to_symbols_sf(modulation[1],modulation[0])
# CHANNEL
isi = gr.fir_filter_fff(1,channel)
diff --git a/gr-trellis/src/python/qa_trellis.py b/gr-trellis/src/python/qa_trellis.py
index fcc651ec6d..935459a3c7 100755
--- a/gr-trellis/src/python/qa_trellis.py
+++ b/gr-trellis/src/python/qa_trellis.py
@@ -114,7 +114,7 @@ class trellis_tb(gr.top_block):
s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol, gr.GR_MSB_FIRST)
# initial FSM state = 0
enc = trellis.encoder_ss(f, 0)
- mod = gr.chunks_to_symbols_sc(constellation.points(), 1)
+ mod = digital_swig.chunks_to_symbols_sc(constellation.points(), 1)
# CHANNEL
add = gr.add_cc()
diff --git a/gr-uhd/gnuradio-uhd.pc.in b/gr-uhd/gnuradio-uhd.pc.in
index 383ad6011b..721141c520 100644
--- a/gr-uhd/gnuradio-uhd.pc.in
+++ b/gr-uhd/gnuradio-uhd.pc.in
@@ -3,7 +3,7 @@ exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
-Name: gnuradio-qtgui
+Name: gnuradio-uhd
Description: GNU Radio blocks for UHD
Requires: gnuradio-core
Version: @LIBVER@
diff --git a/gr-wavelet/lib/CMakeLists.txt b/gr-wavelet/lib/CMakeLists.txt
index 76da7e5347..2d4382b765 100644
--- a/gr-wavelet/lib/CMakeLists.txt
+++ b/gr-wavelet/lib/CMakeLists.txt
@@ -21,20 +21,18 @@
# Setup the include and linker paths
########################################################################
include_directories(
- ${GNURADIO_CORE_INCLUDE_DIRS}
${GR_WAVELET_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
+ ${GNURADIO_CORE_INCLUDE_DIRS}
+ ${Boost_INCLUDE_DIRS}
+ ${GSL_INCLUDE_DIRS}
)
-include_directories(${WAVELET_INCLUDE_DIRS})
link_directories(${WAVELET_LIBRARY_DIRS})
-
-include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
-
-include_directories(${GSL_INCLUDE_DIRS})
link_directories(${GSL_LIBRARY_DIRS})
+add_definitions(${GSL_DEFINITIONS})
########################################################################
# Setup library
diff --git a/gr-wavelet/python/CMakeLists.txt b/gr-wavelet/python/CMakeLists.txt
index 650299672e..f118683954 100644
--- a/gr-wavelet/python/CMakeLists.txt
+++ b/gr-wavelet/python/CMakeLists.txt
@@ -41,7 +41,7 @@ foreach(py_qa_test_file ${py_qa_test_files})
${CMAKE_BINARY_DIR}/gr-wavelet/python
${CMAKE_BINARY_DIR}/gr-wavelet/swig
)
- set(GR_TEST_TARGET_DEPS gruel gnuradio-core gnuradio-wavelet)
- GR_ADD_TEST(${py_qa_test_name} ${PYTHON_EXECUTABLE} ${py_qa_test_file})
+ set(GR_TEST_TARGET_DEPS volk gruel gnuradio-core gnuradio-wavelet)
+ GR_ADD_TEST(${py_qa_test_name} ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} ${py_qa_test_file})
endforeach(py_qa_test_file)
endif(ENABLE_TESTING)
diff --git a/gr-wavelet/swig/CMakeLists.txt b/gr-wavelet/swig/CMakeLists.txt
index 82d083dea2..2c5f433ebb 100644
--- a/gr-wavelet/swig/CMakeLists.txt
+++ b/gr-wavelet/swig/CMakeLists.txt
@@ -30,7 +30,7 @@ set(GR_SWIG_INCLUDE_DIRS
)
set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/wavelet_swig_doc.i)
-set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../lib)
+set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../include/wavelet)
set(GR_SWIG_LIBRARIES gnuradio-wavelet ${GSL_LDFLAGS})
diff --git a/gr-wxgui/CMakeLists.txt b/gr-wxgui/CMakeLists.txt
index 0fc26dee1c..8150c7d802 100644
--- a/gr-wxgui/CMakeLists.txt
+++ b/gr-wxgui/CMakeLists.txt
@@ -76,7 +76,7 @@ install(
########################################################################
install(
FILES ${CMAKE_CURRENT_SOURCE_DIR}/gr-wxgui.conf
- DESTINATION ${GR_PKG_CONF_DIR}
+ DESTINATION ${GR_PREFSDIR}
COMPONENT "wxgui"
)
diff --git a/gr-wxgui/grc/wxgui_fftsink2.xml b/gr-wxgui/grc/wxgui_fftsink2.xml
index ec5501838a..74ee5b173e 100644
--- a/gr-wxgui/grc/wxgui_fftsink2.xml
+++ b/gr-wxgui/grc/wxgui_fftsink2.xml
@@ -36,6 +36,12 @@ fftsink2.$(type.fcn)(
$(parent).Add(self.$(id).win)
#else
$(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
+#end if
+#if $freqvar() is not None
+def $(id)_callback(x, y):
+ self.set_$(freqvar)(x)
+
+self.$(id).set_callback($(id)_callback)
#end if</make>
<callback>set_baseband_freq($baseband_freq)</callback>
<callback>set_sample_rate($samp_rate)</callback>
@@ -216,6 +222,12 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
<value></value>
<type>notebook</type>
</param>
+ <param>
+ <name>Freq Set Varname</name>
+ <key>freqvar</key>
+ <value>None</value>
+ <type>raw</type>
+ </param>
<check>not $win_size or len($win_size) == 2</check>
<sink>
<name>in</name>
diff --git a/gr-wxgui/grc/wxgui_waterfallsink2.xml b/gr-wxgui/grc/wxgui_waterfallsink2.xml
index da6a8a3d1a..8921e87f9a 100644
--- a/gr-wxgui/grc/wxgui_waterfallsink2.xml
+++ b/gr-wxgui/grc/wxgui_waterfallsink2.xml
@@ -34,6 +34,12 @@ waterfallsink2.$(type.fcn)(
$(parent).Add(self.$(id).win)
#else
$(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
+#end if
+#if $freqvar() is not None
+def $(id)_callback(x, y):
+ self.set_$(freqvar)(x)
+
+self.$(id).set_callback($(id)_callback)
#end if</make>
<callback>set_baseband_freq($baseband_freq)</callback>
<callback>set_sample_rate($samp_rate)</callback>
@@ -173,6 +179,12 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
<value></value>
<type>notebook</type>
</param>
+ <param>
+ <name>Freq Set Varname</name>
+ <key>freqvar</key>
+ <value>None</value>
+ <type>raw</type>
+ </param>
<check>not $win_size or len($win_size) == 2</check>
<sink>
<name>in</name>
diff --git a/gr-wxgui/src/python/fft_window.py b/gr-wxgui/src/python/fft_window.py
index 99c1cf6e1a..fac83a4a34 100644
--- a/gr-wxgui/src/python/fft_window.py
+++ b/gr-wxgui/src/python/fft_window.py
@@ -300,6 +300,8 @@ class fft_window(wx.Panel, pubsub.pubsub):
#initial update
self.update_grid()
+ def set_callback(self,callb):
+ self.plotter.set_callback(callb)
def autoscale(self, *args):
"""
diff --git a/gr-wxgui/src/python/fftsink_gl.py b/gr-wxgui/src/python/fftsink_gl.py
index 6b268f6cb2..dc31e84a10 100644
--- a/gr-wxgui/src/python/fftsink_gl.py
+++ b/gr-wxgui/src/python/fftsink_gl.py
@@ -127,6 +127,9 @@ class _fft_sink_base(gr.hier_block2, common.wxgui_hb):
setattr(self.win, 'set_peak_hold', getattr(self, 'set_peak_hold')) #BACKWARDS
#connect
self.wxgui_connect(self, fft, sink)
+
+ def set_callback(self,callb):
+ self.win.set_callback(callb)
class fft_sink_f(_fft_sink_base):
_fft_chain = blks2.logpwrfft_f
diff --git a/gr-wxgui/src/python/plotter/channel_plotter.py b/gr-wxgui/src/python/plotter/channel_plotter.py
index a3a2b64519..4bcc36fd4c 100644
--- a/gr-wxgui/src/python/plotter/channel_plotter.py
+++ b/gr-wxgui/src/python/plotter/channel_plotter.py
@@ -56,6 +56,7 @@ class channel_plotter(grid_plotter_base):
self._channels = dict()
#init channel plotter
self.register_init(self._init_channel_plotter)
+ self.callback = None
def _init_channel_plotter(self):
"""
@@ -150,6 +151,13 @@ class channel_plotter(grid_plotter_base):
label_str += '\n%s: %s'%(channel, common.eng_format(y_value, self.y_units))
return label_str
+ def _call_callback (self, x_val, y_val):
+ if self.callback != None:
+ self.callback(x_val, y_val)
+
+ def set_callback (self, callback):
+ self.callback = callback
+
def _draw_legend(self):
"""
Draw the legend in the upper right corner.
diff --git a/gr-wxgui/src/python/plotter/common.py b/gr-wxgui/src/python/plotter/common.py
index 6775b70571..88215e039a 100644
--- a/gr-wxgui/src/python/plotter/common.py
+++ b/gr-wxgui/src/python/plotter/common.py
@@ -103,6 +103,7 @@ class point_label_thread(threading.Thread, mutex):
self._plotter.Bind(wx.EVT_MOTION, lambda evt: self.enqueue(evt.GetPosition()))
self._plotter.Bind(wx.EVT_LEAVE_WINDOW, lambda evt: self.enqueue(None))
self._plotter.Bind(wx.EVT_RIGHT_DOWN, lambda evt: plotter.enable_point_label(not plotter.enable_point_label()))
+ self._plotter.Bind(wx.EVT_LEFT_DOWN, lambda evt: plotter.call_freq_callback(evt.GetPosition()))
#start the thread
threading.Thread.__init__(self)
self.start()
diff --git a/gr-wxgui/src/python/plotter/grid_plotter_base.py b/gr-wxgui/src/python/plotter/grid_plotter_base.py
index 5eaa76bc0e..f1bc8f546d 100644
--- a/gr-wxgui/src/python/plotter/grid_plotter_base.py
+++ b/gr-wxgui/src/python/plotter/grid_plotter_base.py
@@ -85,7 +85,19 @@ class grid_plotter_base(plotter_base):
self._point_label_cache.changed(True)
self.update()
self.unlock()
-
+
+ def call_freq_callback(self, coor):
+ x, y = self._point_label_coordinate
+ if x < self.padding_left or x > self.width-self.padding_right: return
+ if y < self.padding_top or y > self.height-self.padding_bottom: return
+ #scale to window bounds
+ x_win_scalar = float(x - self.padding_left)/(self.width-self.padding_left-self.padding_right)
+ y_win_scalar = float((self.height - y) - self.padding_bottom)/(self.height-self.padding_top-self.padding_bottom)
+ #scale to grid bounds
+ x_val = x_win_scalar*(self.x_max-self.x_min) + self.x_min
+ y_val = y_win_scalar*(self.y_max-self.y_min) + self.y_min
+ self._call_callback(x_val, y_val)
+
def enable_grid_aspect_ratio(self, enable=None):
"""
Enable/disable the grid aspect ratio.
diff --git a/gr-wxgui/src/python/plotter/plotter_base.py b/gr-wxgui/src/python/plotter/plotter_base.py
index 5af5803392..2fdd0f20ab 100644
--- a/gr-wxgui/src/python/plotter/plotter_base.py
+++ b/gr-wxgui/src/python/plotter/plotter_base.py
@@ -189,7 +189,10 @@ class plotter_base(wx.glcanvas.GLCanvas, common.mutex):
if self.use_persistence:
if self.clear_accum:
#GL.glClear(GL.GL_ACCUM_BUFFER_BIT)
- GL.glAccum(GL.GL_LOAD, 1.0)
+ try:
+ GL.glAccum(GL.GL_LOAD, 1.0)
+ except:
+ pass
self.clear_accum=False
GL.glAccum(GL.GL_MULT, 1.0-self.persist_alpha)
diff --git a/gr-wxgui/src/python/plotter/waterfall_plotter.py b/gr-wxgui/src/python/plotter/waterfall_plotter.py
index f2456241c0..6a6bf6330e 100644
--- a/gr-wxgui/src/python/plotter/waterfall_plotter.py
+++ b/gr-wxgui/src/python/plotter/waterfall_plotter.py
@@ -110,6 +110,7 @@ class waterfall_plotter(grid_plotter_base):
self._counter = 0
self.set_num_lines(0)
self.set_color_mode(COLORS.keys()[0])
+ self.callback = None
def _init_waterfall(self):
"""
@@ -172,6 +173,13 @@ class waterfall_plotter(grid_plotter_base):
"""
return '%s: %s'%(self.x_label, common.eng_format(x_val, self.x_units))
+ def _call_callback(self, x_val, y_val):
+ if self.callback != None:
+ self.callback(x_val,y_val)
+
+ def set_callback(self,callback):
+ self.callback = callback
+
def _draw_legend(self):
"""
Draw the color scale legend.
diff --git a/gr-wxgui/src/python/waterfall_window.py b/gr-wxgui/src/python/waterfall_window.py
index c78244f042..cd60104d7a 100644
--- a/gr-wxgui/src/python/waterfall_window.py
+++ b/gr-wxgui/src/python/waterfall_window.py
@@ -238,6 +238,9 @@ class waterfall_window(wx.Panel, pubsub.pubsub):
#initial update
self.update_grid()
+ def set_callback(self,callb):
+ self.plotter.set_callback(callb)
+
def autoscale(self, *args):
"""
Autoscale the waterfall plot to the last frame.
diff --git a/gr-wxgui/src/python/waterfallsink_gl.py b/gr-wxgui/src/python/waterfallsink_gl.py
index c2c4e8df7a..b69c5dda0c 100644
--- a/gr-wxgui/src/python/waterfallsink_gl.py
+++ b/gr-wxgui/src/python/waterfallsink_gl.py
@@ -113,6 +113,9 @@ class _waterfall_sink_base(gr.hier_block2, common.wxgui_hb):
#connect
self.wxgui_connect(self, fft, sink)
+ def set_callback(self,callb):
+ self.win.set_callback(callb)
+
class waterfall_sink_f(_waterfall_sink_base):
_fft_chain = blks2.logpwrfft_f
_item_size = gr.sizeof_float
diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt
index f54aa4f809..219bbe1642 100644
--- a/grc/CMakeLists.txt
+++ b/grc/CMakeLists.txt
@@ -75,7 +75,7 @@ configure_file(
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/grc.conf
- DESTINATION ${GR_PKG_CONF_DIR}
+ DESTINATION ${GR_PREFSDIR}
COMPONENT "grc"
)
diff --git a/grc/blocks/block_tree.xml b/grc/blocks/block_tree.xml
index 18bc050bac..2377679b65 100644
--- a/grc/blocks/block_tree.xml
+++ b/grc/blocks/block_tree.xml
@@ -13,7 +13,6 @@
<block>gr_noise_source_x</block>
<block>gr_vector_source_x</block>
<block>random_source_x</block>
- <block>gr_glfsr_source_x</block>
<block>gr_null_source</block>
<block>gr_file_source</block>
<block>blks2_tcp_source</block>
@@ -34,6 +33,7 @@
<block>gr_message_sink</block>
<block>pad_sink</block>
<block>virtual_sink</block>
+ <block>gr_tag_debug</block>
</cat>
<cat>
<name>Operators</name>
@@ -61,6 +61,7 @@
<block>gr_fft_vxx</block>
<block>blks2_logpwrfft_x</block>
+ <block>gr_vector_insert_x</block>
</cat>
<cat>
<name>Type Conversions</name>
@@ -114,8 +115,7 @@
<block>gr_unpacked_to_packed_xx</block>
<block>gr_packed_to_unpacked_xx</block>
<block>gr_unpack_k_bits_bb</block>
- <block>gr_chunks_to_symbols_xx</block>
- <block>gr_map_bb</block>
+ <block>gr_pack_k_bits_bb</block>
</cat>
<cat>
<name>Synchronizers</name>
@@ -127,9 +127,7 @@
<block>gr_pll_freqdet_cf</block>
<block>gr_pll_refout_cc</block>
- <block>gr_pn_correlator_cc</block>
<block>gr_simple_correlator</block>
- <block>gr_simple_framer</block>
<block>blks2_packet_decoder</block>
<block>blks2_packet_encoder</block>
@@ -183,6 +181,7 @@
<block>blks2_rational_resampler_xxx</block>
<block>gr_fractional_interpolator_xx</block>
<block>gr_keep_one_in_n</block>
+ <block>gr_keep_m_in_n</block>
<block>gr_moving_average_xx</block>
<block>gr_iqcomp_cc</block>
<block>gr_dc_blocker</block>
@@ -195,11 +194,6 @@
<block>gr_quadrature_demod_cf</block>
<block>gr_cpfsk_bc</block>
- <block>gr_diff_phasor_cc</block>
-
- <block>gr_diff_encoder_bb</block>
- <block>gr_diff_decoder_bb</block>
-
<block>blks2_wfm_tx</block>
<block>blks2_wfm_rcv</block>
<block>blks2_wfm_rcv_pll</block>
@@ -222,15 +216,8 @@
<block>gr_decode_ccsds_27_fb</block>
</cat>
<cat>
- <name>Line Coding</name>
- <block>gr_scrambler_bb</block>
- <block>gr_descrambler_bb</block>
- <block>gr_additive_scrambler_bb</block>
- </cat>
- <cat>
<name>Probes</name>
<block>gr_probe_avg_mag_sqrd_x</block>
- <block>gr_probe_density_b</block>
<block>gr_probe_signal_f</block>
</cat>
<cat>
diff --git a/grc/blocks/gr_additive_scrambler_bb.xml b/grc/blocks/gr_additive_scrambler_bb.xml
deleted file mode 100644
index a15d6eefbe..0000000000
--- a/grc/blocks/gr_additive_scrambler_bb.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0"?>
-<!--
-###################################################
-## Additive Scrambler
-###################################################
- -->
-<block>
- <name>Additive Scrambler</name>
- <key>gr_additive_scrambler_bb</key>
- <import>from gnuradio import gr</import>
- <make>gr.additive_scrambler_bb($mask, $seed, $len, $count)</make>
- <param>
- <name>Mask</name>
- <key>mask</key>
- <value>0x8A</value>
- <type>hex</type>
- </param>
- <param>
- <name>Seed</name>
- <key>seed</key>
- <value>0x7F</value>
- <type>hex</type>
- </param>
- <param>
- <name>Length</name>
- <key>len</key>
- <value>7</value>
- <type>int</type>
- </param>
- <param>
- <name>Count</name>
- <key>count</key>
- <value>0</value>
- <type>int</type>
- </param>
- <sink>
- <name>in</name>
- <type>byte</type>
- </sink>
- <source>
- <name>out</name>
- <type>byte</type>
- </source>
-</block>
diff --git a/grc/blocks/gr_chunks_to_symbols.xml b/grc/blocks/gr_chunks_to_symbols.xml
deleted file mode 100644
index e9da38e9a5..0000000000
--- a/grc/blocks/gr_chunks_to_symbols.xml
+++ /dev/null
@@ -1,77 +0,0 @@
-<?xml version="1.0"?>
-<!--
-###################################################
-##Chunks to Symbols
-###################################################
- -->
-<block>
- <name>Chunks to Symbols</name>
- <key>gr_chunks_to_symbols_xx</key>
- <import>from gnuradio import gr</import>
- <make>gr.chunks_to_symbols_$(in_type.fcn)$(out_type.fcn)($symbol_table, $dimension)</make>
- <param>
- <name>Input Type</name>
- <key>in_type</key>
- <type>enum</type>
- <option>
- <name>Int</name>
- <key>int</key>
- <opt>fcn:i</opt>
- </option>
- <option>
- <name>Short</name>
- <key>short</key>
- <opt>fcn:s</opt>
- </option>
- <option>
- <name>Byte</name>
- <key>byte</key>
- <opt>fcn:b</opt>
- </option>
- </param>
- <param>
- <name>Output Type</name>
- <key>out_type</key>
- <type>enum</type>
- <option>
- <name>Complex</name>
- <key>complex</key>
- <opt>fcn:c</opt>
- <opt>table:complex_vector</opt>
- </option>
- <option>
- <name>Float</name>
- <key>float</key>
- <opt>fcn:f</opt>
- <opt>table:real_vector</opt>
- </option>
- </param>
- <param>
- <name>Symbol Table</name>
- <key>symbol_table</key>
- <type>$out_type.table</type>
- </param>
- <param>
- <name>Dimension</name>
- <key>dimension</key>
- <value>2</value>
- <type>int</type>
- </param>
- <param>
- <name>Num Ports</name>
- <key>num_ports</key>
- <value>1</value>
- <type>int</type>
- </param>
- <check>$num_ports &gt; 0</check>
- <sink>
- <name>in</name>
- <type>$in_type</type>
- <nports>$num_ports</nports>
- </sink>
- <source>
- <name>out</name>
- <type>$out_type</type>
- <nports>$num_ports</nports>
- </source>
-</block>
diff --git a/grc/blocks/gr_descrambler_bb.xml b/grc/blocks/gr_descrambler_bb.xml
deleted file mode 100644
index 5cfbcc203e..0000000000
--- a/grc/blocks/gr_descrambler_bb.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0"?>
-<!--
-###################################################
-##Descrambler
-###################################################
- -->
-<block>
- <name>Descrambler</name>
- <key>gr_descrambler_bb</key>
- <import>from gnuradio import gr</import>
- <make>gr.descrambler_bb($mask, $seed, $len)</make>
- <param>
- <name>Mask</name>
- <key>mask</key>
- <value>0x8A</value>
- <type>hex</type>
- </param>
- <param>
- <name>Seed</name>
- <key>seed</key>
- <value>0x7F</value>
- <type>hex</type>
- </param>
- <param>
- <name>Length</name>
- <key>len</key>
- <value>7</value>
- <type>int</type>
- </param>
- <sink>
- <name>in</name>
- <type>byte</type>
- </sink>
- <source>
- <name>out</name>
- <type>byte</type>
- </source>
-</block>
diff --git a/grc/blocks/gr_diff_phasor_cc.xml b/grc/blocks/gr_diff_phasor_cc.xml
deleted file mode 100644
index 2b2d7e372c..0000000000
--- a/grc/blocks/gr_diff_phasor_cc.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0"?>
-<!--
-###################################################
-##Differential Phasor
-###################################################
- -->
-<block>
- <name>Differential Phasor</name>
- <key>gr_diff_phasor_cc</key>
- <import>from gnuradio import gr</import>
- <make>gr.diff_phasor_cc()</make>
- <sink>
- <name>in</name>
- <type>complex</type>
- </sink>
- <source>
- <name>out</name>
- <type>complex</type>
- </source>
-</block>
diff --git a/grc/blocks/gr_glfsr_source_x.xml b/grc/blocks/gr_glfsr_source_x.xml
deleted file mode 100644
index 88fb66797b..0000000000
--- a/grc/blocks/gr_glfsr_source_x.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0"?>
-<!--
-###################################################
-##GLFSR Source
-###################################################
- -->
-<block>
- <name>GLFSR Source</name>
- <key>gr_glfsr_source_x</key>
- <import>from gnuradio import gr</import>
- <make>gr.glfsr_source_$(type.fcn)($degree, $repeat, $mask, $seed)</make>
- <param>
- <name>Type</name>
- <key>type</key>
- <type>enum</type>
- <option>
- <name>Float</name>
- <key>float</key>
- <opt>fcn:f</opt>
- </option>
- <option>
- <name>Byte</name>
- <key>byte</key>
- <opt>fcn:b</opt>
- </option>
- </param>
- <param>
- <name>Degree</name>
- <key>degree</key>
- <type>int</type>
- </param>
- <param>
- <name>Repeat</name>
- <key>repeat</key>
- <type>enum</type>
- <option>
- <name>Yes</name>
- <key>True</key>
- </option>
- <option>
- <name>No</name>
- <key>False</key>
- </option>
- </param>
- <param>
- <name>Mask</name>
- <key>mask</key>
- <type>int</type>
- </param>
- <param>
- <name>Seed</name>
- <key>seed</key>
- <type>int</type>
- </param>
- <source>
- <name>out</name>
- <type>$type</type>
- </source>
-</block>
diff --git a/grc/blocks/gr_keep_m_in_n.xml b/grc/blocks/gr_keep_m_in_n.xml
new file mode 100644
index 0000000000..35a1561764
--- /dev/null
+++ b/grc/blocks/gr_keep_m_in_n.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Keep M in N
+###################################################
+ -->
+<block>
+ <name>Keep M in N</name>
+ <key>gr_keep_m_in_n</key>
+ <import>from gnuradio import gr</import>
+ <make>gr.keep_m_in_n($type.size, $m, $n, $offset)</make>
+ <callback>set_offset($offset)</callback>
+ <callback>set_m($m)</callback>
+ <callback>set_n($n)</callback>
+ <param>
+ <name>Type</name>
+ <key>type</key>
+ <type>enum</type>
+ <option>
+ <name>Complex</name>
+ <key>complex</key>
+ <opt>size:gr.sizeof_gr_complex</opt>
+ </option>
+ <option>
+ <name>Float</name>
+ <key>float</key>
+ <opt>size:gr.sizeof_float</opt>
+ </option>
+ <option>
+ <name>Int</name>
+ <key>int</key>
+ <opt>size:gr.sizeof_int</opt>
+ </option>
+ <option>
+ <name>Short</name>
+ <key>short</key>
+ <opt>size:gr.sizeof_short</opt>
+ </option>
+ <option>
+ <name>Byte</name>
+ <key>byte</key>
+ <opt>size:gr.sizeof_char</opt>
+ </option>
+ </param>
+ <param>
+ <name>M</name>
+ <key>m</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>N</name>
+ <key>n</key>
+ <value>2</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>initial offset</name>
+ <key>offset</key>
+ <value>0</value>
+ <type>int</type>
+ </param>
+ <check>$n &gt; 0</check>
+ <check>$m &gt; 0</check>
+ <check>$m &lt; $n</check>
+ <sink>
+ <name>in</name>
+ <type>$type</type>
+ <vlen>1</vlen>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>$type</type>
+ <vlen>1</vlen>
+ </source>
+</block>
diff --git a/grc/blocks/gr_map_bb.xml b/grc/blocks/gr_map_bb.xml
deleted file mode 100644
index 20d6bd2b44..0000000000
--- a/grc/blocks/gr_map_bb.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0"?>
-<!--
-###################################################
-##Map
-###################################################
- -->
-<block>
- <name>Map</name>
- <key>gr_map_bb</key>
- <import>from gnuradio import gr</import>
- <make>gr.map_bb($map)</make>
- <param>
- <name>Map</name>
- <key>map</key>
- <type>int_vector</type>
- </param>
- <sink>
- <name>in</name>
- <type>byte</type>
- </sink>
- <source>
- <name>out</name>
- <type>byte</type>
- </source>
-</block>
diff --git a/grc/blocks/gr_diff_encoder_bb.xml b/grc/blocks/gr_pack_k_bits_bb.xml
index 21241eac22..34e64a5d96 100644
--- a/grc/blocks/gr_diff_encoder_bb.xml
+++ b/grc/blocks/gr_pack_k_bits_bb.xml
@@ -1,17 +1,17 @@
<?xml version="1.0"?>
<!--
###################################################
-##Differential Encoder
+##Pack K Bits
###################################################
-->
<block>
- <name>Differential Encoder</name>
- <key>gr_diff_encoder_bb</key>
+ <name>Pack K Bits</name>
+ <key>gr_pack_k_bits_bb</key>
<import>from gnuradio import gr</import>
- <make>gr.diff_encoder_bb($modulus)</make>
+ <make>gr.pack_k_bits_bb($k)</make>
<param>
- <name>Modulus</name>
- <key>modulus</key>
+ <name>K</name>
+ <key>k</key>
<type>int</type>
</param>
<sink>
@@ -22,4 +22,9 @@
<name>out</name>
<type>byte</type>
</source>
+
+ <doc>
+ Pack K unpacked bits (one bit per byte) into a single packed byte containing k bits and 8 - k zeros.
+ </doc>
+
</block>
diff --git a/grc/blocks/gr_pn_correlator_cc.xml b/grc/blocks/gr_pn_correlator_cc.xml
deleted file mode 100644
index 094f46cdfd..0000000000
--- a/grc/blocks/gr_pn_correlator_cc.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0"?>
-<!--
-###################################################
-##PN Correlator
-###################################################
- -->
-<block>
- <name>PN Correlator</name>
- <key>gr_pn_correlator_cc</key>
- <import>from gnuradio import gr</import>
- <make>gr.pn_correlator_cc($degree, $mask, $seed)</make>
- <param>
- <name>Degree</name>
- <key>degree</key>
- <type>int</type>
- </param>
- <param>
- <name>Mask</name>
- <key>mask</key>
- <type>int</type>
- </param>
- <param>
- <name>Seed</name>
- <key>seed</key>
- <type>int</type>
- </param>
- <sink>
- <name>in</name>
- <type>complex</type>
- </sink>
- <source>
- <name>out</name>
- <type>complex</type>
- </source>
-</block>
diff --git a/grc/blocks/gr_probe_density_b.xml b/grc/blocks/gr_probe_density_b.xml
deleted file mode 100644
index 3a91256aa5..0000000000
--- a/grc/blocks/gr_probe_density_b.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0"?>
-<!--
-###################################################
-##Probe Density
-###################################################
- -->
-<block>
- <name>Probe Density</name>
- <key>gr_probe_density_b</key>
- <import>from gnuradio import gr</import>
- <make>gr.probe_density_b($alpha)</make>
- <callback>set_alpha($alpha)</callback>
- <param>
- <name>Alpha</name>
- <key>alpha</key>
- <value>1</value>
- <type>real</type>
- </param>
- <param>
- <name>Probe Rate</name>
- <key>probe_rate</key>
- <value>10</value>
- <type>real</type>
- </param>
- <sink>
- <name>in</name>
- <type>byte</type>
- </sink>
- <doc>
-Available functions to probe: density()
-
-Use with the function probe block.
- </doc>
-</block>
diff --git a/grc/blocks/gr_scrambler_bb.xml b/grc/blocks/gr_scrambler_bb.xml
deleted file mode 100644
index d079c4015f..0000000000
--- a/grc/blocks/gr_scrambler_bb.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0"?>
-<!--
-###################################################
-##Descrambler
-###################################################
- -->
-<block>
- <name>Scrambler</name>
- <key>gr_scrambler_bb</key>
- <import>from gnuradio import gr</import>
- <make>gr.scrambler_bb($mask, $seed, $len)</make>
- <param>
- <name>Mask</name>
- <key>mask</key>
- <value>0x8A</value>
- <type>hex</type>
- </param>
- <param>
- <name>Seed</name>
- <key>seed</key>
- <value>0x7F</value>
- <type>hex</type>
- </param>
- <param>
- <name>Length</name>
- <key>len</key>
- <value>7</value>
- <type>int</type>
- </param>
- <sink>
- <name>in</name>
- <type>byte</type>
- </sink>
- <source>
- <name>out</name>
- <type>byte</type>
- </source>
-</block>
diff --git a/grc/blocks/gr_simple_framer.xml b/grc/blocks/gr_simple_framer.xml
deleted file mode 100644
index 2a0295c417..0000000000
--- a/grc/blocks/gr_simple_framer.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0"?>
-<!--
-###################################################
-##Simple Framer
-###################################################
- -->
-<block>
- <name>Simple Framer</name>
- <key>gr_simple_framer</key>
- <import>from gnuradio import gr</import>
- <make>gr.simple_framer($payload_bytesize)</make>
- <param>
- <name>Payload Byte Size</name>
- <key>payload_bytesize</key>
- <type>int</type>
- </param>
- <sink>
- <name>in</name>
- <type>byte</type>
- </sink>
- <source>
- <name>out</name>
- <type>byte</type>
- </source>
-</block>
diff --git a/grc/blocks/gr_tag_debug.xml b/grc/blocks/gr_tag_debug.xml
new file mode 100644
index 0000000000..4af7729be9
--- /dev/null
+++ b/grc/blocks/gr_tag_debug.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## Tag Debug
+###################################################
+ -->
+<block>
+ <name>Tag Debug</name>
+ <key>gr_tag_debug</key>
+ <import>from gnuradio import gr</import>
+ <make>gr.tag_debug($type.size*$vlen, $name)</make>
+ <callback>set_display($display)</callback>
+ <param>
+ <name>Input Type</name>
+ <key>type</key>
+ <type>enum</type>
+ <option>
+ <name>Complex</name>
+ <key>complex</key>
+ <opt>size:gr.sizeof_gr_complex</opt>
+ </option>
+ <option>
+ <name>Float</name>
+ <key>float</key>
+ <opt>size:gr.sizeof_float</opt>
+ </option>
+ <option>
+ <name>Int</name>
+ <key>int</key>
+ <opt>size:gr.sizeof_int</opt>
+ </option>
+ <option>
+ <name>Short</name>
+ <key>short</key>
+ <opt>size:gr.sizeof_short</opt>
+ </option>
+ <option>
+ <name>Byte</name>
+ <key>byte</key>
+ <opt>size:gr.sizeof_char</opt>
+ </option>
+ </param>
+ <param>
+ <name>Name</name>
+ <key>name</key>
+ <type>string</type>
+ </param>
+ <param>
+ <name>Num Inputs</name>
+ <key>num_inputs</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Vec Length</name>
+ <key>vlen</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Display</name>
+ <key>display</key>
+ <value>True</value>
+ <type>bool</type>
+ <option>
+ <name>On</name>
+ <key>True</key>
+ </option>
+ <option>
+ <name>Off</name>
+ <key>False</key>
+ </option>
+ </param>
+ <check>$num_inputs &gt;= 1</check>
+ <check>$vlen &gt; 0</check>
+ <sink>
+ <name>in</name>
+ <type>$type</type>
+ <vlen>$vlen</vlen>
+ <nports>$num_inputs</nports>
+ </sink>
+</block>
diff --git a/grc/blocks/gr_vector_insert_x.xml b/grc/blocks/gr_vector_insert_x.xml
new file mode 100644
index 0000000000..f9ce1f6544
--- /dev/null
+++ b/grc/blocks/gr_vector_insert_x.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Vector Source
+###################################################
+ -->
+<block>
+ <name>Vector Insert</name>
+ <key>gr_vector_insert_x</key>
+ <import>from gnuradio import gr</import>
+ <make>gr.vector_insert_$(type.fcn)($vector, $period, $offset)</make>
+ <param>
+ <name>Output Type</name>
+ <key>type</key>
+ <type>enum</type>
+ <option>
+ <name>Byte</name>
+ <key>byte</key>
+ <opt>fcn:b</opt>
+ <opt>vec_type:int_vector</opt>
+ </option>
+ <option>
+ <name>Complex</name>
+ <key>complex</key>
+ <opt>fcn:c</opt>
+ <opt>vec_type:complex_vector</opt>
+ </option>
+ <option>
+ <name>Float</name>
+ <key>float</key>
+ <opt>fcn:f</opt>
+ <opt>vec_type:real_vector</opt>
+ </option>
+ <option>
+ <name>Int</name>
+ <key>int</key>
+ <opt>fcn:i</opt>
+ <opt>vec_type:int_vector</opt>
+ </option>
+ <option>
+ <name>Short</name>
+ <key>short</key>
+ <opt>fcn:s</opt>
+ <opt>vec_type:int_vector</opt>
+ </option>
+ </param>
+ <param>
+ <name>Vector</name>
+ <key>vector</key>
+ <value>0, 0, 0</value>
+ <type>$type.vec_type</type>
+ </param>
+ <param>
+ <name>Periodicity</name>
+ <key>period</key>
+ <value>100</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Offset</name>
+ <key>offset</key>
+ <value>0</value>
+ <type>int</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>$type</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>$type</type>
+ </source>
+
+ <doc>
+ Periodicity, the length of the periodicity at which the vector should be inserted at the output.
+ (i.e. one vector for every N output items)
+
+ Offset sepcifies where in the cycle period we should begin at.
+ </doc>
+</block>
diff --git a/grc/grc_gnuradio/blks2/packet.py b/grc/grc_gnuradio/blks2/packet.py
index e39f55c841..494afa986a 100644
--- a/grc/grc_gnuradio/blks2/packet.py
+++ b/grc/grc_gnuradio/blks2/packet.py
@@ -1,4 +1,4 @@
-# Copyright 2008, 2009 Free Software Foundation, Inc.
+# Copyright 2008, 2009, 2012 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -158,7 +158,7 @@ class packet_decoder(gr.hier_block2):
#blocks
msgq = gr.msg_queue(DEFAULT_MSGQ_LIMIT) #holds packets from the PHY
correlator = digital.correlate_access_code_bb(self._access_code, self._threshold)
- framer_sink = gr.framer_sink_1(msgq)
+ framer_sink = digital.framer_sink_1(msgq)
#initialize hier2
gr.hier_block2.__init__(
self,
diff --git a/grc/python/Port.py b/grc/python/Port.py
index d0ef51b483..9f8b50d052 100644
--- a/grc/python/Port.py
+++ b/grc/python/Port.py
@@ -139,6 +139,10 @@ class Port(_Port, _GUIPort):
self._type = ''
self._vlen = ''
+ def resolve_virtual_source(self):
+ if self.get_parent().is_virtual_sink(): return _get_source_from_virtual_sink_port(self)
+ if self.get_parent().is_virtual_source(): return _get_source_from_virtual_source_port(self)
+
def resolve_empty_type(self):
if self.is_sink():
try:
diff --git a/gruel/src/include/gruel/CMakeLists.txt b/gruel/src/include/gruel/CMakeLists.txt
index 9818f1c09c..d4c36eddbb 100644
--- a/gruel/src/include/gruel/CMakeLists.txt
+++ b/gruel/src/include/gruel/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright 2010-2011 Free Software Foundation, Inc.
+# Copyright 2010-2012 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -18,30 +18,12 @@
# Boston, MA 02110-1301, USA.
########################################################################
-# Generate inet.h header file
-########################################################################
-include(TestBigEndian)
-enable_language(C)
-TEST_BIG_ENDIAN(GR_ARCH_BIGENDIAN)
-
-include(CheckIncludeFileCXX)
-CHECK_INCLUDE_FILE_CXX(byteswap.h GR_HAVE_BYTESWAP)
-CHECK_INCLUDE_FILE_CXX(arpa/inet.h GR_HAVE_ARPA_INET)
-CHECK_INCLUDE_FILE_CXX(netinet/in.h GR_HAVE_NETINET_IN)
-
-configure_file(
- ${CMAKE_CURRENT_SOURCE_DIR}/inet.h.in
- ${CMAKE_CURRENT_BINARY_DIR}/inet.h
-@ONLY)
-
-########################################################################
# Install the headers
########################################################################
install(FILES
api.h
attributes.h
high_res_timer.h
- ${CMAKE_CURRENT_BINARY_DIR}/inet.h
msg_accepter.h
msg_accepter_msgq.h
msg_queue.h
diff --git a/gruel/src/include/gruel/inet.h.in b/gruel/src/include/gruel/inet.h.in
deleted file mode 100644
index 74f14bd923..0000000000
--- a/gruel/src/include/gruel/inet.h.in
+++ /dev/null
@@ -1,100 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008, 2009 Free Software Foundation, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef INCLUDED_INET_H
-#define INCLUDED_INET_H
-
-#include <gruel/api.h>
-#include <stdint.h>
-
-#if 1 /* missing htonll or ntohll */
-#if @GR_ARCH_BIGENDIAN@ /* GR_ARCH_BIGENDIAN */
-// Nothing to do...
-static inline uint64_t htonll(uint64_t x){ return x;}
-static inline uint64_t ntohll(uint64_t x){ return x;}
-#else
-#if @GR_HAVE_BYTESWAP@ /* GR_HAVE_BYTESWAP */
-#include <byteswap.h>
-#else
-
-static inline uint64_t
-bswap_64(uint64_t x)
-{
- return ((x & 0x00000000000000ffull) << 56) | ((x & 0x000000000000ff00ull) << 40) |
- ((x & 0x0000000000ff0000ull) << 24) | ((x & 0x00000000ff000000ull) << 8) |
- ((x & 0x000000ff00000000ull) >> 8) | ((x & 0x0000ff0000000000ull) >> 24) |
- ((x & 0x00ff000000000000ull) >> 40) | ((x & 0xff00000000000000ull) >> 56);
-}
-
-#endif /* GR_HAVE_BYTESWAP */
-
-static inline uint64_t htonll(uint64_t x){ return bswap_64(x);}
-static inline uint64_t ntohll(uint64_t x){ return bswap_64(x);}
-
-#endif /* GR_ARCH_BIGENDIAN */
-#endif /* missing htonll or ntohll */
-
-#if @GR_HAVE_ARPA_INET@ /* GR_HAVE_ARPA_INET */
-#include <arpa/inet.h>
-#elif @GR_HAVE_NETINET_IN@ /* GR_HAVE_NETINET_IN */
-#include <netinet/in.h>
-#else
-#include <stdint.h>
-
-#if @GR_ARCH_BIGENDIAN@ /* GR_ARCH_BIGENDIAN */
-// Nothing to do...
-static inline uint32_t htonl(uint32_t x){ return x; }
-static inline uint16_t htons(uint16_t x){ return x; }
-static inline uint32_t ntohl(uint32_t x){ return x; }
-static inline uint16_t ntohs(uint16_t x){ return x; }
-#else
-#if @GR_HAVE_BYTESWAP@ /* GR_HAVE_BYTESWAP */
-#include <byteswap.h>
-#else
-static inline uint16_t
-bswap_16 (uint16_t x)
-{
- return ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8));
-}
-
-static inline uint32_t
-bswap_32 (uint32_t x)
-{
- return ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) \
- | (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24));
-}
-#endif /* GR_HAVE_BYTESWAP */
-
-static inline uint32_t htonl(uint32_t x){ return bswap_32(x); }
-static inline uint16_t htons(uint16_t x){ return bswap_16(x); }
-static inline uint32_t ntohl(uint32_t x){ return bswap_32(x); }
-static inline uint16_t ntohs(uint16_t x){ return bswap_16(x); }
-#endif /* GR_ARCH_BIGENDIAN */
-
-#endif /* !(GR_HAVE_NETINET_IN || GR_HAVE_ARPA_INET) */
-
-static inline uint8_t ntohx(uint8_t x){ return x; }
-static inline uint16_t ntohx(uint16_t x){ return ntohs(x); }
-static inline uint32_t ntohx(uint32_t x){ return ntohl(x); }
-static inline uint64_t ntohx(uint64_t x){ return ntohll(x);}
-static inline uint8_t htonx(uint8_t x){ return x; }
-static inline uint16_t htonx(uint16_t x){ return htons(x); }
-static inline uint32_t htonx(uint32_t x){ return htonl(x); }
-static inline uint64_t htonx(uint64_t x){ return htonll(x);}
-
-#endif /* INCLUDED_INET_H */
diff --git a/gruel/src/lib/pmt/pmt-serial-tags.scm b/gruel/src/lib/pmt/pmt-serial-tags.scm
index ca25a43a8a..4f06bf75f8 100644
--- a/gruel/src/lib/pmt/pmt-serial-tags.scm
+++ b/gruel/src/lib/pmt/pmt-serial-tags.scm
@@ -33,6 +33,8 @@
(define pst-dict #x09) ; untagged-int32 n; followed by n key/value tuples
(define pst-uniform-vector #x0a)
+(define pst-uint64 #x0b)
+(define pst-tuple #x0c)
;; u8, s8, u16, s16, u32, s32, u64, s64, f32, f64, c32, c64
;;
diff --git a/gruel/src/lib/pmt/pmt_serialize.cc b/gruel/src/lib/pmt/pmt_serialize.cc
index de9644c3c6..a19809a667 100644
--- a/gruel/src/lib/pmt/pmt_serialize.cc
+++ b/gruel/src/lib/pmt/pmt_serialize.cc
@@ -79,7 +79,6 @@ serialize_untagged_f64(double i, std::streambuf &sb)
}
-#if 0
// always writes big-endian
static bool
serialize_untagged_u64(uint64_t i, std::streambuf &sb)
@@ -93,7 +92,6 @@ serialize_untagged_u64(uint64_t i, std::streambuf &sb)
sb.sputc((i >> 8) & 0xff);
return sb.sputc((i >> 0) & 0xff) != std::streambuf::traits_type::eof();
}
-#endif
// ----------------------------------------------------------------
// input primitives
@@ -152,7 +150,6 @@ deserialize_untagged_u32(uint32_t *ip, std::streambuf &sb)
return t != std::streambuf::traits_type::eof();
}
-#if 0
// always reads big-endian
static bool
deserialize_untagged_u64(uint64_t *ip, std::streambuf &sb)
@@ -181,7 +178,6 @@ deserialize_untagged_u64(uint64_t *ip, std::streambuf &sb)
*ip = i;
return t != std::streambuf::traits_type::eof();
}
-#endif
static bool
deserialize_untagged_f64(double *ip, std::streambuf &sb)
@@ -217,6 +213,24 @@ deserialize_untagged_f64(double *ip, std::streambuf &sb)
return t != std::streambuf::traits_type::eof();
}
+static bool
+deserialize_tuple(pmt_t *tuple, std::streambuf &sb)
+{
+ uint32_t nitems;
+ bool ok = deserialize_untagged_u32(&nitems, sb);
+ pmt_t list(PMT_NIL);
+ for(uint32_t i=0; i<nitems; i++){
+ pmt_t item = pmt_deserialize( sb );
+ if(pmt_eq(list, PMT_NIL)){
+ list = pmt_list1(item);
+ } else {
+ list = pmt_list_add(list, item);
+ }
+ }
+ (*tuple) = pmt_to_tuple(list);
+ return ok;
+}
+
/*
* Write portable byte-serial representation of \p obj to \p sb
@@ -260,7 +274,13 @@ pmt_serialize(pmt_t obj, std::streambuf &sb)
}
if (pmt_is_number(obj)){
-
+
+ if (pmt_is_uint64(obj)){
+ uint64_t i = pmt_to_uint64(obj);
+ ok = serialize_untagged_u8(PST_UINT64, sb);
+ ok &= serialize_untagged_u64(i, sb);
+ return ok;
+ } else
if (pmt_is_integer(obj)){
long i = pmt_to_long(obj);
if (sizeof(long) > 4){
@@ -298,6 +318,16 @@ pmt_serialize(pmt_t obj, std::streambuf &sb)
if (pmt_is_dict(obj))
throw pmt_notimplemented("pmt_serialize (dict)", obj);
+ if (pmt_is_tuple(obj)){
+ size_t tuple_len = pmt::pmt_length(obj);
+ ok = serialize_untagged_u8(PST_TUPLE, sb);
+ ok &= serialize_untagged_u32(tuple_len, sb);
+ for(size_t i=0; i<tuple_len; i++){
+ ok &= pmt_serialize(pmt_tuple_ref(obj, i), sb);
+ }
+ return ok;
+ }
+ //throw pmt_notimplemented("pmt_serialize (tuple)", obj);
throw pmt_notimplemented("pmt_serialize (?)", obj);
}
@@ -315,7 +345,7 @@ pmt_deserialize(std::streambuf &sb)
//uint8_t u8;
uint16_t u16;
uint32_t u32;
- //uint32_t u64;
+ uint64_t u64;
double f64;
static char tmpbuf[1024];
@@ -347,6 +377,11 @@ pmt_deserialize(std::streambuf &sb)
goto error;
return pmt_from_long((int32_t) u32);
+ case PST_UINT64:
+ if(!deserialize_untagged_u64(&u64, sb))
+ goto error;
+ return pmt_from_uint64(u64);
+
case PST_PAIR:
return parse_pair(sb);
@@ -362,6 +397,15 @@ pmt_deserialize(std::streambuf &sb)
goto error;
return pmt_make_rectangular( r,i );
}
+
+ case PST_TUPLE:
+ {
+ pmt_t tuple;
+ if(!deserialize_tuple(&tuple, sb)){
+ goto error;
+ }
+ return tuple;
+ }
case PST_VECTOR:
case PST_DICT:
diff --git a/gruel/src/swig/CMakeLists.txt b/gruel/src/swig/CMakeLists.txt
index f9d1758ec4..a0f84c8323 100644
--- a/gruel/src/swig/CMakeLists.txt
+++ b/gruel/src/swig/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright 2011 Free Software Foundation, Inc.
+# Copyright 2011-2012 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -23,7 +23,7 @@
include(GrPython)
include(GrSwig)
-set(GR_SWIG_INCLUDE_DIRS ${GRUEL_INCLUDE_DIRS})
+set(GR_SWIG_INCLUDE_DIRS ${GRUEL_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR})
set(GR_SWIG_LIBRARIES gruel)
set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/pmt_swig_doc.i)
diff --git a/volk/apps/volk_profile.cc b/volk/apps/volk_profile.cc
index 0b44421085..6244abb357 100644
--- a/volk/apps/volk_profile.cc
+++ b/volk/apps/volk_profile.cc
@@ -33,6 +33,7 @@ int main(int argc, char *argv[]) {
//VOLK_PROFILE(volk_16i_permute_and_scalar_add_a, 1e-4, 0, 2046, 10000, &results);
//VOLK_PROFILE(volk_16i_x4_quad_max_star_16i_a, 1e-4, 0, 2046, 10000, &results);
VOLK_PROFILE(volk_16u_byteswap_a, 0, 0, 204600, 10000, &results);
+ VOLK_PROFILE(volk_16i_32fc_dot_prod_32fc_a, 1e-4, 0, 204600, 10000, &results);
VOLK_PROFILE(volk_32f_accumulator_s32f_a, 1e-4, 0, 204600, 10000, &results);
VOLK_PROFILE(volk_32f_x2_add_32f_a, 1e-4, 0, 204600, 10000, &results);
VOLK_PROFILE(volk_32f_x2_add_32f_u, 1e-4, 0, 204600, 10000, &results);
@@ -49,6 +50,7 @@ int main(int argc, char *argv[]) {
VOLK_PROFILE(volk_32fc_deinterleave_real_32f_a, 1e-4, 0, 204600, 5000, &results);
VOLK_PROFILE(volk_32fc_deinterleave_real_64f_a, 1e-4, 0, 204600, 1000, &results);
VOLK_PROFILE(volk_32fc_x2_dot_prod_32fc_a, 1e-4, 0, 204600, 10000, &results);
+ VOLK_PROFILE(volk_32fc_32f_dot_prod_32fc_a, 1e-4, 0, 204600, 10000, &results);
VOLK_PROFILE(volk_32fc_index_max_16u_a, 3, 0, 204600, 10000, &results);
VOLK_PROFILE(volk_32fc_s32f_magnitude_16i_a, 1, 32768, 204600, 100, &results);
VOLK_PROFILE(volk_32fc_magnitude_32f_a, 1e-4, 0, 204600, 1000, &results);
@@ -76,6 +78,7 @@ int main(int argc, char *argv[]) {
VOLK_PROFILE(volk_32f_x2_divide_32f_a, 1e-4, 0, 204600, 2000, &results);
VOLK_PROFILE(volk_32f_x2_dot_prod_32f_a, 1e-4, 0, 204600, 5000, &results);
VOLK_PROFILE(volk_32f_x2_dot_prod_32f_u, 1e-4, 0, 204600, 5000, &results);
+ VOLK_PROFILE(volk_32f_x2_dot_prod_16i_a, 1e-4, 0, 204600, 5000, &results);
//VOLK_PROFILE(volk_32f_s32f_32f_fm_detect_32f_a, 1e-4, 2046, 10000, &results);
VOLK_PROFILE(volk_32f_index_max_16u_a, 3, 0, 204600, 5000, &results);
VOLK_PROFILE(volk_32f_x2_s32f_interleave_16ic_a, 1, 32768, 204600, 3000, &results);
diff --git a/volk/gen/archs.xml b/volk/gen/archs.xml
index 2c9ab41a55..a18455801d 100644
--- a/volk/gen/archs.xml
+++ b/volk/gen/archs.xml
@@ -2,6 +2,7 @@
<grammar>
<arch name="generic"> <!-- name is required-->
+ <alignment>1</alignment>
</arch>
<arch name="altivec">
diff --git a/volk/include/volk/volk_16i_32fc_dot_prod_32fc_a.h b/volk/include/volk/volk_16i_32fc_dot_prod_32fc_a.h
new file mode 100644
index 0000000000..940aa5de7c
--- /dev/null
+++ b/volk/include/volk/volk_16i_32fc_dot_prod_32fc_a.h
@@ -0,0 +1,122 @@
+#ifndef INCLUDED_volk_16i_32fc_dot_prod_32fc_a_H
+#define INCLUDED_volk_16i_32fc_dot_prod_32fc_a_H
+
+#include <volk/volk_common.h>
+#include<stdio.h>
+
+
+#ifdef LV_HAVE_GENERIC
+
+
+static inline void volk_16i_32fc_dot_prod_32fc_a_generic(lv_32fc_t* result, const short* input, const lv_32fc_t * taps, unsigned int num_points) {
+
+ static const int N_UNROLL = 4;
+
+ lv_32fc_t acc0 = 0;
+ lv_32fc_t acc1 = 0;
+ lv_32fc_t acc2 = 0;
+ lv_32fc_t acc3 = 0;
+
+ unsigned i = 0;
+ unsigned n = (num_points / N_UNROLL) * N_UNROLL;
+
+ for(i = 0; i < n; i += N_UNROLL) {
+ acc0 += taps[i + 0] * (float)input[i + 0];
+ acc1 += taps[i + 1] * (float)input[i + 1];
+ acc2 += taps[i + 2] * (float)input[i + 2];
+ acc3 += taps[i + 3] * (float)input[i + 3];
+ }
+
+ for(; i < num_points; i++) {
+ acc0 += taps[i] * (float)input[i];
+ }
+
+ *result = acc0 + acc1 + acc2 + acc3;
+}
+
+#endif /*LV_HAVE_GENERIC*/
+
+
+#ifdef LV_HAVE_SSE
+
+
+static inline void volk_16i_32fc_dot_prod_32fc_a_sse( lv_32fc_t* result, const short* input, const lv_32fc_t* taps, unsigned int num_points) {
+
+ unsigned int number = 0;
+ const unsigned int sixteenthPoints = num_points / 8;
+
+ float res[2];
+ float *realpt = &res[0], *imagpt = &res[1];
+ const short* aPtr = input;
+ const float* bPtr = (float*)taps;
+
+ __m64 m0, m1;
+ __m128 f0, f1, f2, f3;
+ __m128 a0Val, a1Val, a2Val, a3Val;
+ __m128 b0Val, b1Val, b2Val, b3Val;
+ __m128 c0Val, c1Val, c2Val, c3Val;
+
+ __m128 dotProdVal0 = _mm_setzero_ps();
+ __m128 dotProdVal1 = _mm_setzero_ps();
+ __m128 dotProdVal2 = _mm_setzero_ps();
+ __m128 dotProdVal3 = _mm_setzero_ps();
+
+ for(;number < sixteenthPoints; number++){
+
+ m0 = _mm_set_pi16(*(aPtr+3), *(aPtr+2), *(aPtr+1), *(aPtr+0));
+ m1 = _mm_set_pi16(*(aPtr+7), *(aPtr+6), *(aPtr+5), *(aPtr+4));
+ f0 = _mm_cvtpi16_ps(m0);
+ f1 = _mm_cvtpi16_ps(m0);
+ f2 = _mm_cvtpi16_ps(m1);
+ f3 = _mm_cvtpi16_ps(m1);
+
+ a0Val = _mm_unpacklo_ps(f0, f1);
+ a1Val = _mm_unpackhi_ps(f0, f1);
+ a2Val = _mm_unpacklo_ps(f2, f3);
+ a3Val = _mm_unpackhi_ps(f2, f3);
+
+ b0Val = _mm_load_ps(bPtr);
+ b1Val = _mm_load_ps(bPtr+4);
+ b2Val = _mm_load_ps(bPtr+8);
+ b3Val = _mm_load_ps(bPtr+12);
+
+ c0Val = _mm_mul_ps(a0Val, b0Val);
+ c1Val = _mm_mul_ps(a1Val, b1Val);
+ c2Val = _mm_mul_ps(a2Val, b2Val);
+ c3Val = _mm_mul_ps(a3Val, b3Val);
+
+ dotProdVal0 = _mm_add_ps(c0Val, dotProdVal0);
+ dotProdVal1 = _mm_add_ps(c1Val, dotProdVal1);
+ dotProdVal2 = _mm_add_ps(c2Val, dotProdVal2);
+ dotProdVal3 = _mm_add_ps(c3Val, dotProdVal3);
+
+ aPtr += 8;
+ bPtr += 16;
+ }
+
+ dotProdVal0 = _mm_add_ps(dotProdVal0, dotProdVal1);
+ dotProdVal0 = _mm_add_ps(dotProdVal0, dotProdVal2);
+ dotProdVal0 = _mm_add_ps(dotProdVal0, dotProdVal3);
+
+ __VOLK_ATTR_ALIGNED(16) float dotProductVector[4];
+
+ _mm_store_ps(dotProductVector,dotProdVal0); // Store the results back into the dot product vector
+
+ *realpt = dotProductVector[0];
+ *imagpt = dotProductVector[1];
+ *realpt += dotProductVector[2];
+ *imagpt += dotProductVector[3];
+
+ number = sixteenthPoints*8;
+ for(;number < num_points; number++){
+ *realpt += ((*aPtr) * (*bPtr++));
+ *imagpt += ((*aPtr++) * (*bPtr++));
+ }
+
+ *result = *(lv_32fc_t*)(&res[0]);
+}
+
+#endif /*LV_HAVE_SSE*/
+
+
+#endif /*INCLUDED_volk_16i_32fc_dot_prod_32fc_a_H*/
diff --git a/volk/include/volk/volk_32f_x2_dot_prod_16i_a.h b/volk/include/volk/volk_32f_x2_dot_prod_16i_a.h
new file mode 100644
index 0000000000..961c2418ca
--- /dev/null
+++ b/volk/include/volk/volk_32f_x2_dot_prod_16i_a.h
@@ -0,0 +1,98 @@
+#ifndef INCLUDED_volk_32f_x2_dot_prod_16i_a_H
+#define INCLUDED_volk_32f_x2_dot_prod_16i_a_H
+
+#include <volk/volk_common.h>
+#include<stdio.h>
+
+
+#ifdef LV_HAVE_GENERIC
+
+
+static inline void volk_32f_x2_dot_prod_16i_a_generic(int16_t* result, const float* input, const float* taps, unsigned int num_points) {
+
+ float dotProduct = 0;
+ const float* aPtr = input;
+ const float* bPtr= taps;
+ unsigned int number = 0;
+
+ for(number = 0; number < num_points; number++){
+ dotProduct += ((*aPtr++) * (*bPtr++));
+ }
+
+ *result = (int16_t)dotProduct;
+}
+
+#endif /*LV_HAVE_GENERIC*/
+
+
+#ifdef LV_HAVE_SSE
+
+
+static inline void volk_32f_x2_dot_prod_16i_a_sse(int16_t* result, const float* input, const float* taps, unsigned int num_points) {
+
+ unsigned int number = 0;
+ const unsigned int sixteenthPoints = num_points / 16;
+
+ float dotProduct = 0;
+ const float* aPtr = input;
+ const float* bPtr = taps;
+
+ __m128 a0Val, a1Val, a2Val, a3Val;
+ __m128 b0Val, b1Val, b2Val, b3Val;
+ __m128 c0Val, c1Val, c2Val, c3Val;
+
+ __m128 dotProdVal0 = _mm_setzero_ps();
+ __m128 dotProdVal1 = _mm_setzero_ps();
+ __m128 dotProdVal2 = _mm_setzero_ps();
+ __m128 dotProdVal3 = _mm_setzero_ps();
+
+ for(;number < sixteenthPoints; number++){
+
+ a0Val = _mm_load_ps(aPtr);
+ a1Val = _mm_load_ps(aPtr+4);
+ a2Val = _mm_load_ps(aPtr+8);
+ a3Val = _mm_load_ps(aPtr+12);
+ b0Val = _mm_load_ps(bPtr);
+ b1Val = _mm_load_ps(bPtr+4);
+ b2Val = _mm_load_ps(bPtr+8);
+ b3Val = _mm_load_ps(bPtr+12);
+
+ c0Val = _mm_mul_ps(a0Val, b0Val);
+ c1Val = _mm_mul_ps(a1Val, b1Val);
+ c2Val = _mm_mul_ps(a2Val, b2Val);
+ c3Val = _mm_mul_ps(a3Val, b3Val);
+
+ dotProdVal0 = _mm_add_ps(c0Val, dotProdVal0);
+ dotProdVal1 = _mm_add_ps(c1Val, dotProdVal1);
+ dotProdVal2 = _mm_add_ps(c2Val, dotProdVal2);
+ dotProdVal3 = _mm_add_ps(c3Val, dotProdVal3);
+
+ aPtr += 16;
+ bPtr += 16;
+ }
+
+ dotProdVal0 = _mm_add_ps(dotProdVal0, dotProdVal1);
+ dotProdVal0 = _mm_add_ps(dotProdVal0, dotProdVal2);
+ dotProdVal0 = _mm_add_ps(dotProdVal0, dotProdVal3);
+
+ __VOLK_ATTR_ALIGNED(16) float dotProductVector[4];
+
+ _mm_store_ps(dotProductVector,dotProdVal0); // Store the results back into the dot product vector
+
+ dotProduct = dotProductVector[0];
+ dotProduct += dotProductVector[1];
+ dotProduct += dotProductVector[2];
+ dotProduct += dotProductVector[3];
+
+ number = sixteenthPoints*16;
+ for(;number < num_points; number++){
+ dotProduct += ((*aPtr++) * (*bPtr++));
+ }
+
+ *result = (short)dotProduct;
+
+}
+
+#endif /*LV_HAVE_SSE*/
+
+#endif /*INCLUDED_volk_32f_x2_dot_prod_16i_a_H*/
diff --git a/volk/include/volk/volk_32f_x2_dot_prod_32f_a.h b/volk/include/volk/volk_32f_x2_dot_prod_32f_a.h
index 448b2fdc01..067c33ad89 100644
--- a/volk/include/volk/volk_32f_x2_dot_prod_32f_a.h
+++ b/volk/include/volk/volk_32f_x2_dot_prod_32f_a.h
@@ -31,39 +31,60 @@ static inline void volk_32f_x2_dot_prod_32f_a_generic(float * result, const floa
static inline void volk_32f_x2_dot_prod_32f_a_sse( float* result, const float* input, const float* taps, unsigned int num_points) {
unsigned int number = 0;
- const unsigned int quarterPoints = num_points / 4;
+ const unsigned int sixteenthPoints = num_points / 16;
float dotProduct = 0;
const float* aPtr = input;
const float* bPtr = taps;
- __m128 aVal, bVal, cVal;
-
- __m128 dotProdVal = _mm_setzero_ps();
-
- for(;number < quarterPoints; number++){
+ __m128 a0Val, a1Val, a2Val, a3Val;
+ __m128 b0Val, b1Val, b2Val, b3Val;
+ __m128 c0Val, c1Val, c2Val, c3Val;
- aVal = _mm_load_ps(aPtr);
- bVal = _mm_load_ps(bPtr);
+ __m128 dotProdVal0 = _mm_setzero_ps();
+ __m128 dotProdVal1 = _mm_setzero_ps();
+ __m128 dotProdVal2 = _mm_setzero_ps();
+ __m128 dotProdVal3 = _mm_setzero_ps();
- cVal = _mm_mul_ps(aVal, bVal);
-
- dotProdVal = _mm_add_ps(cVal, dotProdVal);
+ for(;number < sixteenthPoints; number++){
- aPtr += 4;
- bPtr += 4;
+ a0Val = _mm_load_ps(aPtr);
+ a1Val = _mm_load_ps(aPtr+4);
+ a2Val = _mm_load_ps(aPtr+8);
+ a3Val = _mm_load_ps(aPtr+12);
+ b0Val = _mm_load_ps(bPtr);
+ b1Val = _mm_load_ps(bPtr+4);
+ b2Val = _mm_load_ps(bPtr+8);
+ b3Val = _mm_load_ps(bPtr+12);
+
+ c0Val = _mm_mul_ps(a0Val, b0Val);
+ c1Val = _mm_mul_ps(a1Val, b1Val);
+ c2Val = _mm_mul_ps(a2Val, b2Val);
+ c3Val = _mm_mul_ps(a3Val, b3Val);
+
+ dotProdVal0 = _mm_add_ps(c0Val, dotProdVal0);
+ dotProdVal1 = _mm_add_ps(c1Val, dotProdVal1);
+ dotProdVal2 = _mm_add_ps(c2Val, dotProdVal2);
+ dotProdVal3 = _mm_add_ps(c3Val, dotProdVal3);
+
+ aPtr += 16;
+ bPtr += 16;
}
+ dotProdVal0 = _mm_add_ps(dotProdVal0, dotProdVal1);
+ dotProdVal0 = _mm_add_ps(dotProdVal0, dotProdVal2);
+ dotProdVal0 = _mm_add_ps(dotProdVal0, dotProdVal3);
+
__VOLK_ATTR_ALIGNED(16) float dotProductVector[4];
- _mm_store_ps(dotProductVector,dotProdVal); // Store the results back into the dot product vector
+ _mm_store_ps(dotProductVector,dotProdVal0); // Store the results back into the dot product vector
dotProduct = dotProductVector[0];
dotProduct += dotProductVector[1];
dotProduct += dotProductVector[2];
dotProduct += dotProductVector[3];
- number = quarterPoints * 4;
+ number = sixteenthPoints*16;
for(;number < num_points; number++){
dotProduct += ((*aPtr++) * (*bPtr++));
}
@@ -80,38 +101,59 @@ static inline void volk_32f_x2_dot_prod_32f_a_sse( float* result, const float*
static inline void volk_32f_x2_dot_prod_32f_a_sse3(float * result, const float * input, const float * taps, unsigned int num_points) {
unsigned int number = 0;
- const unsigned int quarterPoints = num_points / 4;
+ const unsigned int sixteenthPoints = num_points / 16;
float dotProduct = 0;
const float* aPtr = input;
const float* bPtr = taps;
- __m128 aVal, bVal, cVal;
-
- __m128 dotProdVal = _mm_setzero_ps();
-
- for(;number < quarterPoints; number++){
+ __m128 a0Val, a1Val, a2Val, a3Val;
+ __m128 b0Val, b1Val, b2Val, b3Val;
+ __m128 c0Val, c1Val, c2Val, c3Val;
- aVal = _mm_load_ps(aPtr);
- bVal = _mm_load_ps(bPtr);
+ __m128 dotProdVal0 = _mm_setzero_ps();
+ __m128 dotProdVal1 = _mm_setzero_ps();
+ __m128 dotProdVal2 = _mm_setzero_ps();
+ __m128 dotProdVal3 = _mm_setzero_ps();
- cVal = _mm_mul_ps(aVal, bVal);
-
- dotProdVal = _mm_hadd_ps(dotProdVal, cVal);
+ for(;number < sixteenthPoints; number++){
- aPtr += 4;
- bPtr += 4;
+ a0Val = _mm_load_ps(aPtr);
+ a1Val = _mm_load_ps(aPtr+4);
+ a2Val = _mm_load_ps(aPtr+8);
+ a3Val = _mm_load_ps(aPtr+12);
+ b0Val = _mm_load_ps(bPtr);
+ b1Val = _mm_load_ps(bPtr+4);
+ b2Val = _mm_load_ps(bPtr+8);
+ b3Val = _mm_load_ps(bPtr+12);
+
+ c0Val = _mm_mul_ps(a0Val, b0Val);
+ c1Val = _mm_mul_ps(a1Val, b1Val);
+ c2Val = _mm_mul_ps(a2Val, b2Val);
+ c3Val = _mm_mul_ps(a3Val, b3Val);
+
+ dotProdVal0 = _mm_add_ps(dotProdVal0, c0Val);
+ dotProdVal1 = _mm_add_ps(dotProdVal1, c1Val);
+ dotProdVal2 = _mm_add_ps(dotProdVal2, c2Val);
+ dotProdVal3 = _mm_add_ps(dotProdVal3, c3Val);
+
+ aPtr += 16;
+ bPtr += 16;
}
- __VOLK_ATTR_ALIGNED(16) float dotProductVector[4];
- dotProdVal = _mm_hadd_ps(dotProdVal, dotProdVal);
+ dotProdVal0 = _mm_add_ps(dotProdVal0, dotProdVal1);
+ dotProdVal0 = _mm_add_ps(dotProdVal0, dotProdVal2);
+ dotProdVal0 = _mm_add_ps(dotProdVal0, dotProdVal3);
- _mm_store_ps(dotProductVector,dotProdVal); // Store the results back into the dot product vector
+ __VOLK_ATTR_ALIGNED(16) float dotProductVector[4];
+ _mm_store_ps(dotProductVector,dotProdVal0); // Store the results back into the dot product vector
dotProduct = dotProductVector[0];
dotProduct += dotProductVector[1];
+ dotProduct += dotProductVector[2];
+ dotProduct += dotProductVector[3];
- number = quarterPoints * 4;
+ number = sixteenthPoints*16;
for(;number < num_points; number++){
dotProduct += ((*aPtr++) * (*bPtr++));
}
@@ -182,4 +224,67 @@ static inline void volk_32f_x2_dot_prod_32f_a_sse4_1(float * result, const float
#endif /*LV_HAVE_SSE4_1*/
+#ifdef LV_HAVE_AVX
+
+#include <immintrin.h>
+
+static inline void volk_32f_x2_dot_prod_32f_a_avx( float* result, const float* input, const float* taps, unsigned int num_points) {
+
+ unsigned int number = 0;
+ const unsigned int sixteenthPoints = num_points / 16;
+
+ float dotProduct = 0;
+ const float* aPtr = input;
+ const float* bPtr = taps;
+
+ __m256 a0Val, a1Val;
+ __m256 b0Val, b1Val;
+ __m256 c0Val, c1Val;
+
+ __m256 dotProdVal0 = _mm256_setzero_ps();
+ __m256 dotProdVal1 = _mm256_setzero_ps();
+
+ for(;number < sixteenthPoints; number++){
+
+ a0Val = _mm256_load_ps(aPtr);
+ a1Val = _mm256_load_ps(aPtr+8);
+ b0Val = _mm256_load_ps(bPtr);
+ b1Val = _mm256_load_ps(bPtr+8);
+
+ c0Val = _mm256_mul_ps(a0Val, b0Val);
+ c1Val = _mm256_mul_ps(a1Val, b1Val);
+
+ dotProdVal0 = _mm256_add_ps(c0Val, dotProdVal0);
+ dotProdVal1 = _mm256_add_ps(c1Val, dotProdVal1);
+
+ aPtr += 16;
+ bPtr += 16;
+ }
+
+ dotProdVal0 = _mm256_add_ps(dotProdVal0, dotProdVal1);
+
+ __VOLK_ATTR_ALIGNED(32) float dotProductVector[8];
+
+ _mm256_store_ps(dotProductVector,dotProdVal0); // Store the results back into the dot product vector
+
+ dotProduct = dotProductVector[0];
+ dotProduct += dotProductVector[1];
+ dotProduct += dotProductVector[2];
+ dotProduct += dotProductVector[3];
+ dotProduct += dotProductVector[4];
+ dotProduct += dotProductVector[5];
+ dotProduct += dotProductVector[6];
+ dotProduct += dotProductVector[7];
+
+ number = sixteenthPoints*16;
+ for(;number < num_points; number++){
+ dotProduct += ((*aPtr++) * (*bPtr++));
+ }
+
+ *result = dotProduct;
+
+}
+
+#endif /*LV_HAVE_AVX*/
+
#endif /*INCLUDED_volk_32f_x2_dot_prod_32f_a_H*/
diff --git a/volk/include/volk/volk_32f_x2_dot_prod_32f_u.h b/volk/include/volk/volk_32f_x2_dot_prod_32f_u.h
index 3b7284b575..ab33a25876 100644
--- a/volk/include/volk/volk_32f_x2_dot_prod_32f_u.h
+++ b/volk/include/volk/volk_32f_x2_dot_prod_32f_u.h
@@ -1,6 +1,7 @@
#ifndef INCLUDED_volk_32f_x2_dot_prod_32f_u_H
#define INCLUDED_volk_32f_x2_dot_prod_32f_u_H
+#include <volk/volk_common.h>
#include<stdio.h>
@@ -30,41 +31,65 @@ static inline void volk_32f_x2_dot_prod_32f_u_generic(float * result, const floa
static inline void volk_32f_x2_dot_prod_32f_u_sse( float* result, const float* input, const float* taps, unsigned int num_points) {
unsigned int number = 0;
- const unsigned int quarterPoints = num_points / 4;
+ const unsigned int sixteenthPoints = num_points / 16;
float dotProduct = 0;
const float* aPtr = input;
const float* bPtr = taps;
- __m128 aVal, bVal, cVal;
-
- __m128 dotProdVal = _mm_setzero_ps();
-
- for(;number < quarterPoints; number++){
+ __m128 a0Val, a1Val, a2Val, a3Val;
+ __m128 b0Val, b1Val, b2Val, b3Val;
+ __m128 c0Val, c1Val, c2Val, c3Val;
- aVal = _mm_loadu_ps(aPtr);
- bVal = _mm_loadu_ps(bPtr);
+ __m128 dotProdVal0 = _mm_setzero_ps();
+ __m128 dotProdVal1 = _mm_setzero_ps();
+ __m128 dotProdVal2 = _mm_setzero_ps();
+ __m128 dotProdVal3 = _mm_setzero_ps();
- cVal = _mm_mul_ps(aVal, bVal);
-
- dotProdVal = _mm_add_ps(cVal, dotProdVal);
+ for(;number < sixteenthPoints; number++){
- aPtr += 4;
- bPtr += 4;
+ a0Val = _mm_load_ps(aPtr);
+ a1Val = _mm_load_ps(aPtr+4);
+ a2Val = _mm_load_ps(aPtr+8);
+ a3Val = _mm_load_ps(aPtr+12);
+ b0Val = _mm_load_ps(bPtr);
+ b1Val = _mm_load_ps(bPtr+4);
+ b2Val = _mm_load_ps(bPtr+8);
+ b3Val = _mm_load_ps(bPtr+12);
+
+ c0Val = _mm_mul_ps(a0Val, b0Val);
+ c1Val = _mm_mul_ps(a1Val, b1Val);
+ c2Val = _mm_mul_ps(a2Val, b2Val);
+ c3Val = _mm_mul_ps(a3Val, b3Val);
+
+ dotProdVal0 = _mm_add_ps(c0Val, dotProdVal0);
+ dotProdVal1 = _mm_add_ps(c1Val, dotProdVal1);
+ dotProdVal2 = _mm_add_ps(c2Val, dotProdVal2);
+ dotProdVal3 = _mm_add_ps(c3Val, dotProdVal3);
+
+ aPtr += 16;
+ bPtr += 16;
}
+ dotProdVal0 = _mm_add_ps(dotProdVal0, dotProdVal1);
+ dotProdVal0 = _mm_add_ps(dotProdVal0, dotProdVal2);
+ dotProdVal0 = _mm_add_ps(dotProdVal0, dotProdVal3);
+
__VOLK_ATTR_ALIGNED(16) float dotProductVector[4];
- _mm_store_ps(dotProductVector,dotProdVal); // Store the results back into the dot product vector
+ _mm_store_ps(dotProductVector,dotProdVal0); // Store the results back into the dot product vector
dotProduct = dotProductVector[0];
dotProduct += dotProductVector[1];
dotProduct += dotProductVector[2];
dotProduct += dotProductVector[3];
- number = quarterPoints * 4;
+ number = sixteenthPoints*16;
for(;number < num_points; number++){
dotProduct += ((*aPtr++) * (*bPtr++));
+ dotProduct += ((*aPtr++) * (*bPtr++));
+ dotProduct += ((*aPtr++) * (*bPtr++));
+ dotProduct += ((*aPtr++) * (*bPtr++));
}
*result = dotProduct;
@@ -79,38 +104,59 @@ static inline void volk_32f_x2_dot_prod_32f_u_sse( float* result, const float*
static inline void volk_32f_x2_dot_prod_32f_u_sse3(float * result, const float * input, const float * taps, unsigned int num_points) {
unsigned int number = 0;
- const unsigned int quarterPoints = num_points / 4;
+ const unsigned int sixteenthPoints = num_points / 16;
float dotProduct = 0;
const float* aPtr = input;
const float* bPtr = taps;
- __m128 aVal, bVal, cVal;
-
- __m128 dotProdVal = _mm_setzero_ps();
-
- for(;number < quarterPoints; number++){
+ __m128 a0Val, a1Val, a2Val, a3Val;
+ __m128 b0Val, b1Val, b2Val, b3Val;
+ __m128 c0Val, c1Val, c2Val, c3Val;
- aVal = _mm_loadu_ps(aPtr);
- bVal = _mm_loadu_ps(bPtr);
+ __m128 dotProdVal0 = _mm_setzero_ps();
+ __m128 dotProdVal1 = _mm_setzero_ps();
+ __m128 dotProdVal2 = _mm_setzero_ps();
+ __m128 dotProdVal3 = _mm_setzero_ps();
- cVal = _mm_mul_ps(aVal, bVal);
-
- dotProdVal = _mm_hadd_ps(dotProdVal, cVal);
+ for(;number < sixteenthPoints; number++){
- aPtr += 4;
- bPtr += 4;
+ a0Val = _mm_load_ps(aPtr);
+ a1Val = _mm_load_ps(aPtr+4);
+ a2Val = _mm_load_ps(aPtr+8);
+ a3Val = _mm_load_ps(aPtr+12);
+ b0Val = _mm_load_ps(bPtr);
+ b1Val = _mm_load_ps(bPtr+4);
+ b2Val = _mm_load_ps(bPtr+8);
+ b3Val = _mm_load_ps(bPtr+12);
+
+ c0Val = _mm_mul_ps(a0Val, b0Val);
+ c1Val = _mm_mul_ps(a1Val, b1Val);
+ c2Val = _mm_mul_ps(a2Val, b2Val);
+ c3Val = _mm_mul_ps(a3Val, b3Val);
+
+ dotProdVal0 = _mm_add_ps(dotProdVal0, c0Val);
+ dotProdVal1 = _mm_add_ps(dotProdVal1, c1Val);
+ dotProdVal2 = _mm_add_ps(dotProdVal2, c2Val);
+ dotProdVal3 = _mm_add_ps(dotProdVal3, c3Val);
+
+ aPtr += 16;
+ bPtr += 16;
}
- __VOLK_ATTR_ALIGNED(16) float dotProductVector[4];
- dotProdVal = _mm_hadd_ps(dotProdVal, dotProdVal);
+ dotProdVal0 = _mm_add_ps(dotProdVal0, dotProdVal1);
+ dotProdVal0 = _mm_add_ps(dotProdVal0, dotProdVal2);
+ dotProdVal0 = _mm_add_ps(dotProdVal0, dotProdVal3);
- _mm_store_ps(dotProductVector,dotProdVal); // Store the results back into the dot product vector
+ __VOLK_ATTR_ALIGNED(16) float dotProductVector[4];
+ _mm_store_ps(dotProductVector,dotProdVal0); // Store the results back into the dot product vector
dotProduct = dotProductVector[0];
dotProduct += dotProductVector[1];
+ dotProduct += dotProductVector[2];
+ dotProduct += dotProductVector[3];
- number = quarterPoints * 4;
+ number = sixteenthPoints*16;
for(;number < num_points; number++){
dotProduct += ((*aPtr++) * (*bPtr++));
}
@@ -141,15 +187,15 @@ static inline void volk_32f_x2_dot_prod_32f_u_sse4_1(float * result, const float
for(;number < sixteenthPoints; number++){
- aVal1 = _mm_loadu_ps(aPtr); aPtr += 4;
- aVal2 = _mm_loadu_ps(aPtr); aPtr += 4;
- aVal3 = _mm_loadu_ps(aPtr); aPtr += 4;
- aVal4 = _mm_loadu_ps(aPtr); aPtr += 4;
+ aVal1 = _mm_load_ps(aPtr); aPtr += 4;
+ aVal2 = _mm_load_ps(aPtr); aPtr += 4;
+ aVal3 = _mm_load_ps(aPtr); aPtr += 4;
+ aVal4 = _mm_load_ps(aPtr); aPtr += 4;
- bVal1 = _mm_loadu_ps(bPtr); bPtr += 4;
- bVal2 = _mm_loadu_ps(bPtr); bPtr += 4;
- bVal3 = _mm_loadu_ps(bPtr); bPtr += 4;
- bVal4 = _mm_loadu_ps(bPtr); bPtr += 4;
+ bVal1 = _mm_load_ps(bPtr); bPtr += 4;
+ bVal2 = _mm_load_ps(bPtr); bPtr += 4;
+ bVal3 = _mm_load_ps(bPtr); bPtr += 4;
+ bVal4 = _mm_load_ps(bPtr); bPtr += 4;
cVal1 = _mm_dp_ps(aVal1, bVal1, 0xF1);
cVal2 = _mm_dp_ps(aVal2, bVal2, 0xF2);
@@ -181,4 +227,67 @@ static inline void volk_32f_x2_dot_prod_32f_u_sse4_1(float * result, const float
#endif /*LV_HAVE_SSE4_1*/
+#ifdef LV_HAVE_AVX
+
+#include <immintrin.h>
+
+static inline void volk_32f_x2_dot_prod_32f_u_avx( float* result, const float* input, const float* taps, unsigned int num_points) {
+
+ unsigned int number = 0;
+ const unsigned int sixteenthPoints = num_points / 16;
+
+ float dotProduct = 0;
+ const float* aPtr = input;
+ const float* bPtr = taps;
+
+ __m256 a0Val, a1Val;
+ __m256 b0Val, b1Val;
+ __m256 c0Val, c1Val;
+
+ __m256 dotProdVal0 = _mm256_setzero_ps();
+ __m256 dotProdVal1 = _mm256_setzero_ps();
+
+ for(;number < sixteenthPoints; number++){
+
+ a0Val = _mm256_loadu_ps(aPtr);
+ a1Val = _mm256_loadu_ps(aPtr+8);
+ b0Val = _mm256_loadu_ps(bPtr);
+ b1Val = _mm256_loadu_ps(bPtr+8);
+
+ c0Val = _mm256_mul_ps(a0Val, b0Val);
+ c1Val = _mm256_mul_ps(a1Val, b1Val);
+
+ dotProdVal0 = _mm256_add_ps(c0Val, dotProdVal0);
+ dotProdVal1 = _mm256_add_ps(c1Val, dotProdVal1);
+
+ aPtr += 16;
+ bPtr += 16;
+ }
+
+ dotProdVal0 = _mm256_add_ps(dotProdVal0, dotProdVal1);
+
+ __VOLK_ATTR_ALIGNED(32) float dotProductVector[8];
+
+ _mm256_storeu_ps(dotProductVector,dotProdVal0); // Store the results back into the dot product vector
+
+ dotProduct = dotProductVector[0];
+ dotProduct += dotProductVector[1];
+ dotProduct += dotProductVector[2];
+ dotProduct += dotProductVector[3];
+ dotProduct += dotProductVector[4];
+ dotProduct += dotProductVector[5];
+ dotProduct += dotProductVector[6];
+ dotProduct += dotProductVector[7];
+
+ number = sixteenthPoints*16;
+ for(;number < num_points; number++){
+ dotProduct += ((*aPtr++) * (*bPtr++));
+ }
+
+ *result = dotProduct;
+
+}
+
+#endif /*LV_HAVE_AVX*/
+
#endif /*INCLUDED_volk_32f_x2_dot_prod_32f_u_H*/
diff --git a/volk/include/volk/volk_32fc_32f_dot_prod_32fc_a.h b/volk/include/volk/volk_32fc_32f_dot_prod_32fc_a.h
new file mode 100644
index 0000000000..109b787e8c
--- /dev/null
+++ b/volk/include/volk/volk_32fc_32f_dot_prod_32fc_a.h
@@ -0,0 +1,111 @@
+#ifndef INCLUDED_volk_32fc_32f_dot_prod_32fc_a_H
+#define INCLUDED_volk_32fc_32f_dot_prod_32fc_a_H
+
+#include <volk/volk_common.h>
+#include<stdio.h>
+
+
+#ifdef LV_HAVE_GENERIC
+
+
+static inline void volk_32fc_32f_dot_prod_32fc_a_generic(lv_32fc_t* result, const lv_32fc_t* input, const float * taps, unsigned int num_points) {
+
+ float res[2];
+ float *realpt = &res[0], *imagpt = &res[1];
+ const float* aPtr = (float*)input;
+ const float* bPtr= taps;
+ unsigned int number = 0;
+
+ *realpt = 0;
+ *imagpt = 0;
+
+ for(number = 0; number < num_points; number++){
+ *realpt += ((*aPtr++) * (*bPtr));
+ *imagpt += ((*aPtr++) * (*bPtr++));
+ }
+
+ *result = *(lv_32fc_t*)(&res[0]);
+}
+
+#endif /*LV_HAVE_GENERIC*/
+
+
+#ifdef LV_HAVE_SSE
+
+
+static inline void volk_32fc_32f_dot_prod_32fc_a_sse( lv_32fc_t* result, const lv_32fc_t* input, const float* taps, unsigned int num_points) {
+
+ unsigned int number = 0;
+ const unsigned int sixteenthPoints = num_points / 8;
+
+ float res[2];
+ float *realpt = &res[0], *imagpt = &res[1];
+ const float* aPtr = (float*)input;
+ const float* bPtr = taps;
+
+ __m128 a0Val, a1Val, a2Val, a3Val;
+ __m128 b0Val, b1Val, b2Val, b3Val;
+ __m128 x0Val, x1Val, x2Val, x3Val;
+ __m128 c0Val, c1Val, c2Val, c3Val;
+
+ __m128 dotProdVal0 = _mm_setzero_ps();
+ __m128 dotProdVal1 = _mm_setzero_ps();
+ __m128 dotProdVal2 = _mm_setzero_ps();
+ __m128 dotProdVal3 = _mm_setzero_ps();
+
+ for(;number < sixteenthPoints; number++){
+
+ a0Val = _mm_load_ps(aPtr);
+ a1Val = _mm_load_ps(aPtr+4);
+ a2Val = _mm_load_ps(aPtr+8);
+ a3Val = _mm_load_ps(aPtr+12);
+
+ x0Val = _mm_load_ps(bPtr);
+ x1Val = _mm_load_ps(bPtr);
+ x2Val = _mm_load_ps(bPtr+4);
+ x3Val = _mm_load_ps(bPtr+4);
+ b0Val = _mm_unpacklo_ps(x0Val, x1Val);
+ b1Val = _mm_unpackhi_ps(x0Val, x1Val);
+ b2Val = _mm_unpacklo_ps(x2Val, x3Val);
+ b3Val = _mm_unpackhi_ps(x2Val, x3Val);
+
+ c0Val = _mm_mul_ps(a0Val, b0Val);
+ c1Val = _mm_mul_ps(a1Val, b1Val);
+ c2Val = _mm_mul_ps(a2Val, b2Val);
+ c3Val = _mm_mul_ps(a3Val, b3Val);
+
+ dotProdVal0 = _mm_add_ps(c0Val, dotProdVal0);
+ dotProdVal1 = _mm_add_ps(c1Val, dotProdVal1);
+ dotProdVal2 = _mm_add_ps(c2Val, dotProdVal2);
+ dotProdVal3 = _mm_add_ps(c3Val, dotProdVal3);
+
+ aPtr += 16;
+ bPtr += 8;
+ }
+
+ dotProdVal0 = _mm_add_ps(dotProdVal0, dotProdVal1);
+ dotProdVal0 = _mm_add_ps(dotProdVal0, dotProdVal2);
+ dotProdVal0 = _mm_add_ps(dotProdVal0, dotProdVal3);
+
+ __VOLK_ATTR_ALIGNED(16) float dotProductVector[4];
+
+ _mm_store_ps(dotProductVector,dotProdVal0); // Store the results back into the dot product vector
+
+ *realpt = dotProductVector[0];
+ *imagpt = dotProductVector[1];
+ *realpt += dotProductVector[2];
+ *imagpt += dotProductVector[3];
+
+ number = sixteenthPoints*8;
+ for(;number < num_points; number++){
+ *realpt += ((*aPtr++) * (*bPtr));
+ *imagpt += ((*aPtr++) * (*bPtr++));
+ }
+
+ *result = *(lv_32fc_t*)(&res[0]);
+}
+
+#endif /*LV_HAVE_SSE*/
+
+
+#endif /*INCLUDED_volk_32fc_32f_dot_prod_32fc_a_H*/
diff --git a/volk/include/volk/volk_32fc_s32fc_x2_rotator_32fc_a.h b/volk/include/volk/volk_32fc_s32fc_x2_rotator_32fc_a.h
index 80c55e75f3..05732b1eab 100644
--- a/volk/include/volk/volk_32fc_s32fc_x2_rotator_32fc_a.h
+++ b/volk/include/volk/volk_32fc_s32fc_x2_rotator_32fc_a.h
@@ -174,12 +174,10 @@ static inline void volk_32fc_s32fc_x2_rotator_32fc_a_avx(lv_32fc_t* outVector, c
printf("%f, %f\n", lv_creal(phase_Ptr[2]), lv_cimag(phase_Ptr[2]));
printf("%f, %f\n", lv_creal(phase_Ptr[3]), lv_cimag(phase_Ptr[3]));
printf("incr: %f, %f\n", lv_creal(incr), lv_cimag(incr));*/
- __m256 aVal, phase_Val, inc_Val, yl, yh, tmp1, tmp2, z, ylp, yhp, tmp1p, tmp2p, negated, zeros;
+ __m256 aVal, phase_Val, inc_Val, yl, yh, tmp1, tmp2, z, ylp, yhp, tmp1p, tmp2p;
phase_Val = _mm256_loadu_ps((float*)phase_Ptr);
inc_Val = _mm256_set_ps(lv_cimag(incr), lv_creal(incr),lv_cimag(incr), lv_creal(incr),lv_cimag(incr), lv_creal(incr),lv_cimag(incr), lv_creal(incr));
- zeros = _mm256_set1_ps(0.0);
- negated = _mm256_set1_ps(-1.0);
const unsigned int fourthPoints = num_points / 4;
diff --git a/volk/include/volk/volk_32fc_x2_dot_prod_32fc_a.h b/volk/include/volk/volk_32fc_x2_dot_prod_32fc_a.h
index cb2ac4c67e..166a883a7f 100644
--- a/volk/include/volk/volk_32fc_x2_dot_prod_32fc_a.h
+++ b/volk/include/volk/volk_32fc_x2_dot_prod_32fc_a.h
@@ -18,40 +18,26 @@ static inline void volk_32fc_x2_dot_prod_32fc_a_generic(lv_32fc_t* result, const
unsigned int n_2_ccomplex_blocks = num_bytes >> 4;
unsigned int isodd = (num_bytes >> 3) &1;
-
-
float sum0[2] = {0,0};
float sum1[2] = {0,0};
unsigned int i = 0;
-
for(i = 0; i < n_2_ccomplex_blocks; ++i) {
-
-
sum0[0] += in[0] * tp[0] - in[1] * tp[1];
sum0[1] += in[0] * tp[1] + in[1] * tp[0];
sum1[0] += in[2] * tp[2] - in[3] * tp[3];
sum1[1] += in[2] * tp[3] + in[3] * tp[2];
-
in += 4;
tp += 4;
-
}
-
res[0] = sum0[0] + sum1[0];
res[1] = sum0[1] + sum1[1];
-
-
for(i = 0; i < isodd; ++i) {
-
-
*result += input[(num_bytes >> 3) - 1] * taps[(num_bytes >> 3) - 1];
-
}
-
}
#endif /*LV_HAVE_GENERIC*/
@@ -177,14 +163,8 @@ static inline void volk_32fc_x2_dot_prod_32fc_a_sse_64(lv_32fc_t* result, const
);
- int getem = num_bytes % 16;
-
-
- for(; getem > 0; getem -= 8) {
-
-
+ if(((num_bytes >> 3) & 1)) {
*result += (input[(num_bytes >> 3) - 1] * taps[(num_bytes >> 3) - 1]);
-
}
return;
@@ -363,7 +343,7 @@ static inline void volk_32fc_x2_dot_prod_32fc_a_sse3(lv_32fc_t* result, const lv
dotProduct += ( dotProductVector[0] + dotProductVector[1] );
- if((num_bytes >> 2) != 0) {
+ if(((num_bytes >> 3) & 1) != 0) {
dotProduct += (*a) * (*b);
}
@@ -377,9 +357,7 @@ static inline void volk_32fc_x2_dot_prod_32fc_a_sse3(lv_32fc_t* result, const lv
#include <smmintrin.h>
static inline void volk_32fc_x2_dot_prod_32fc_a_sse4_1(lv_32fc_t* result, const lv_32fc_t* input, const lv_32fc_t* taps, unsigned int num_bytes) {
- volk_32fc_x2_dot_prod_32fc_a_sse3(result, input, taps, num_bytes);
- // SSE3 version runs twice as fast as the SSE4.1 version, so turning off SSE4 version for now
- /*
+
__m128 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, real0, real1, im0, im1;
float *p_input, *p_taps;
__m64 *p_result;
@@ -442,12 +420,8 @@ static inline void volk_32fc_x2_dot_prod_32fc_a_sse4_1(lv_32fc_t* result, const
}
-
-
-
real1 = _mm_xor_ps(real1, (__m128)neg);
-
im0 = _mm_add_ps(im0, im1);
real0 = _mm_add_ps(real0, real1);
@@ -459,7 +433,6 @@ static inline void volk_32fc_x2_dot_prod_32fc_a_sse4_1(lv_32fc_t* result, const
*result += input[i] * taps[i];
}
- */
}
#endif /*LV_HAVE_SSE4_1*/
diff --git a/volk/lib/testqa.cc b/volk/lib/testqa.cc
index aac6767298..d1eb1cacbb 100644
--- a/volk/lib/testqa.cc
+++ b/volk/lib/testqa.cc
@@ -20,6 +20,7 @@ VOLK_RUN_TESTS(volk_16i_convert_8i_u, 0, 0, 20460, 1);
//VOLK_RUN_TESTS(volk_16i_permute_and_scalar_add_a, 1e-4, 0, 2046, 1000);
//VOLK_RUN_TESTS(volk_16i_x4_quad_max_star_16i_a, 1e-4, 0, 2046, 1000);
VOLK_RUN_TESTS(volk_16u_byteswap_a, 0, 0, 20460, 1);
+//VOLK_RUN_TESTS(volk_16i_32fc_dot_prod_32fc_a, 1e-4, 0, 204600, 1);
VOLK_RUN_TESTS(volk_32f_accumulator_s32f_a, 1e-4, 0, 20460, 1);
VOLK_RUN_TESTS(volk_32f_x2_add_32f_a, 1e-4, 0, 20460, 1);
VOLK_RUN_TESTS(volk_32f_x2_add_32f_u, 1e-4, 0, 20460, 1);
@@ -34,7 +35,8 @@ VOLK_RUN_TESTS(volk_32fc_deinterleave_64f_x2_a, 1e-4, 0, 20460, 1);
VOLK_RUN_TESTS(volk_32fc_s32f_deinterleave_real_16i_a, 0, 32768, 20460, 1);
VOLK_RUN_TESTS(volk_32fc_deinterleave_real_32f_a, 1e-4, 0, 20460, 1);
VOLK_RUN_TESTS(volk_32fc_deinterleave_real_64f_a, 1e-4, 0, 20460, 1);
-VOLK_RUN_TESTS(volk_32fc_x2_dot_prod_32fc_a, 1e-4, 0, 204600, 1);
+VOLK_RUN_TESTS(volk_32fc_x2_dot_prod_32fc_a, 1e-4, 0, 2046000, 1);
+VOLK_RUN_TESTS(volk_32fc_32f_dot_prod_32fc_a, 1e-4, 0, 2046000, 1);
VOLK_RUN_TESTS(volk_32fc_index_max_16u_a, 3, 0, 20460, 1);
VOLK_RUN_TESTS(volk_32fc_s32f_magnitude_16i_a, 1, 32768, 20460, 1);
VOLK_RUN_TESTS(volk_32fc_magnitude_32f_a, 1e-4, 0, 20460, 1);
@@ -52,7 +54,8 @@ VOLK_RUN_TESTS(volk_32fc_x2_square_dist_32f_a, 1e-4, 0, 20460, 1);
VOLK_RUN_TESTS(volk_32fc_x2_s32f_square_dist_scalar_mult_32f_a, 1e-4, 10, 20460, 1);
VOLK_RUN_TESTS(volk_32f_x2_divide_32f_a, 1e-4, 0, 20460, 1);
VOLK_RUN_TESTS(volk_32f_x2_dot_prod_32f_a, 1e-4, 0, 204600, 1);
-VOLK_RUN_TESTS(volk_32f_x2_dot_prod_32f_u, 1e-4, 0, 204600, 1);
+//VOLK_RUN_TESTS(volk_32f_x2_dot_prod_32f_u, 1e-4, 0, 204600, 1);
+VOLK_RUN_TESTS(volk_32f_x2_dot_prod_16i_a, 1e-4, 0, 204600, 1);
//VOLK_RUN_TESTS(volk_32f_s32f_32f_fm_detect_32f_a, 1e-4, 2046, 10000);
VOLK_RUN_TESTS(volk_32f_index_max_16u_a, 3, 0, 20460, 1);
VOLK_RUN_TESTS(volk_32f_x2_s32f_interleave_16ic_a, 1, 32767, 20460, 1);