summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt4
-rw-r--r--cmake/Modules/FindUHD.cmake24
-rw-r--r--docs/doxygen/Doxyfile.in27
-rw-r--r--docs/doxygen/other/pmt.dox17
-rw-r--r--docs/doxygen/other/stream_tags.dox5
-rw-r--r--gnuradio-runtime/include/gnuradio/block.h14
-rw-r--r--gnuradio-runtime/include/gnuradio/block_detail.h5
-rw-r--r--gnuradio-runtime/include/gnuradio/buffer.h10
-rw-r--r--gnuradio-runtime/include/gnuradio/logger.h.in7
-rw-r--r--gnuradio-runtime/include/gnuradio/tagged_stream_block.h2
-rw-r--r--gnuradio-runtime/include/pmt/pmt.h10
-rw-r--r--gnuradio-runtime/lib/basic_block.cc2
-rw-r--r--gnuradio-runtime/lib/block.cc12
-rw-r--r--gnuradio-runtime/lib/block_detail.cc13
-rw-r--r--gnuradio-runtime/lib/buffer.cc58
-rw-r--r--gnuradio-runtime/lib/logger.cc31
-rw-r--r--gnuradio-runtime/lib/pmt/pmt.cc12
-rw-r--r--gnuradio-runtime/lib/pmt/qa_pmt_prims.cc9
-rw-r--r--gnuradio-runtime/lib/tagged_stream_block.cc12
-rw-r--r--gnuradio-runtime/python/gnuradio/gr/tag_utils.py17
-rwxr-xr-xgnuradio-runtime/python/pmt/qa_pmt.py2
-rw-r--r--gnuradio-runtime/swig/block.i1
-rw-r--r--gnuradio-runtime/swig/pmt_swig.i2
-rw-r--r--gr-analog/grc/analog_probe_avg_mag_sqrd_x.xml1
-rw-r--r--gr-analog/include/gnuradio/analog/probe_avg_mag_sqrd_c.h1
-rw-r--r--gr-analog/include/gnuradio/analog/probe_avg_mag_sqrd_cf.h1
-rw-r--r--gr-analog/include/gnuradio/analog/probe_avg_mag_sqrd_f.h1
-rw-r--r--gr-analog/lib/probe_avg_mag_sqrd_c_impl.cc6
-rw-r--r--gr-analog/lib/probe_avg_mag_sqrd_c_impl.h1
-rw-r--r--gr-analog/lib/probe_avg_mag_sqrd_cf_impl.cc6
-rw-r--r--gr-analog/lib/probe_avg_mag_sqrd_cf_impl.h1
-rw-r--r--gr-analog/lib/probe_avg_mag_sqrd_f_impl.cc6
-rw-r--r--gr-analog/lib/probe_avg_mag_sqrd_f_impl.h1
-rw-r--r--gr-blocks/examples/CMakeLists.txt8
-rw-r--r--gr-blocks/examples/msg_passing/strobe.grc182
-rw-r--r--gr-blocks/examples/vector_source_with_tags.grc698
-rw-r--r--gr-blocks/grc/blocks_abs_xx.xml19
-rw-r--r--gr-blocks/grc/blocks_tagged_stream_to_pdu.xml1
-rw-r--r--gr-blocks/include/gnuradio/blocks/abs_XX.h.t2
-rw-r--r--gr-blocks/include/gnuradio/blocks/control_loop.h81
-rw-r--r--gr-blocks/include/gnuradio/blocks/pdu_to_tagged_stream.h4
-rw-r--r--gr-blocks/lib/abs_XX_impl.cc.t13
-rw-r--r--gr-blocks/lib/abs_XX_impl.h.t5
-rw-r--r--gr-blocks/lib/deinterleave_impl.cc36
-rw-r--r--gr-blocks/lib/deinterleave_impl.h3
-rw-r--r--gr-blocks/lib/message_strobe_impl.cc8
-rw-r--r--gr-blocks/lib/message_strobe_impl.h2
-rw-r--r--gr-blocks/lib/message_strobe_random_impl.cc4
-rw-r--r--gr-blocks/lib/message_strobe_random_impl.h2
-rw-r--r--gr-blocks/lib/pdu_to_tagged_stream_impl.cc119
-rw-r--r--gr-blocks/lib/pdu_to_tagged_stream_impl.h15
-rw-r--r--gr-blocks/lib/qa_block_tags.cc198
-rw-r--r--gr-blocks/lib/throttle_impl.cc8
-rw-r--r--gr-blocks/lib/throttle_impl.h3
-rw-r--r--gr-blocks/lib/udp_sink_impl.cc5
-rw-r--r--gr-blocks/lib/udp_source_impl.cc3
-rw-r--r--gr-blocks/lib/vector_source_X_impl.cc.t2
-rwxr-xr-xgr-blocks/python/blocks/qa_pdu.py2
-rw-r--r--gr-digital/grc/digital_costas_loop_cc.xml84
-rw-r--r--gr-digital/include/gnuradio/digital/costas_loop_cc.h9
-rw-r--r--gr-digital/include/gnuradio/digital/ofdm_frame_equalizer_vcvc.h17
-rw-r--r--gr-digital/lib/costas_loop_cc_impl.cc68
-rw-r--r--gr-digital/lib/costas_loop_cc_impl.h45
-rw-r--r--gr-digital/lib/header_payload_demux_impl.cc71
-rw-r--r--gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc66
-rw-r--r--gr-digital/lib/ofdm_serializer_vcc_impl.cc80
-rwxr-xr-xgr-digital/python/digital/qa_costas_loop_cc.py22
-rwxr-xr-xgr-digital/python/digital/qa_header_payload_demux.py80
-rwxr-xr-xgr-digital/python/digital/qa_ofdm_frame_equalizer_vcvc.py2
-rw-r--r--gr-fec/lib/decoder_impl.cc8
-rw-r--r--gr-fec/lib/encoder_impl.cc12
-rw-r--r--gr-fft/include/gnuradio/fft/window.h23
-rw-r--r--gr-fft/lib/window.cc20
-rw-r--r--gr-qtgui/grc/qtgui_freq_sink_x.xml81
-rw-r--r--gr-qtgui/grc/qtgui_waterfall_sink_x.xml19
-rw-r--r--gr-qtgui/include/gnuradio/qtgui/FrequencyDisplayPlot.h3
-rw-r--r--gr-qtgui/include/gnuradio/qtgui/WaterfallDisplayPlot.h2
-rw-r--r--gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h28
-rw-r--r--gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h35
-rw-r--r--gr-qtgui/include/gnuradio/qtgui/freqdisplayform.h28
-rw-r--r--gr-qtgui/include/gnuradio/qtgui/waterfall_sink_f.h7
-rw-r--r--gr-qtgui/include/gnuradio/qtgui/waterfalldisplayform.h1
-rw-r--r--gr-qtgui/lib/FrequencyDisplayPlot.cc34
-rw-r--r--gr-qtgui/lib/WaterfallDisplayPlot.cc31
-rw-r--r--gr-qtgui/lib/const_sink_c_impl.cc2
-rw-r--r--gr-qtgui/lib/freq_sink_c_impl.cc225
-rw-r--r--gr-qtgui/lib/freq_sink_c_impl.h24
-rw-r--r--gr-qtgui/lib/freq_sink_f_impl.cc219
-rw-r--r--gr-qtgui/lib/freq_sink_f_impl.h27
-rw-r--r--gr-qtgui/lib/freqdisplayform.cc119
-rw-r--r--gr-qtgui/lib/waterfall_sink_f_impl.cc23
-rw-r--r--gr-qtgui/lib/waterfall_sink_f_impl.h1
-rw-r--r--gr-qtgui/lib/waterfalldisplayform.cc7
-rw-r--r--gr-trellis/doc/gr-trellis.xml8
-rw-r--r--gr-trellis/examples/grc/CMakeLists.txt26
-rw-r--r--gr-trellis/examples/grc/interference_cancellation.grc2635
-rw-r--r--gr-trellis/examples/grc/pccc.grc833
-rw-r--r--gr-trellis/examples/grc/readme.txt6
-rw-r--r--gr-trellis/examples/grc/sccc.grc690
-rw-r--r--gr-trellis/examples/grc/tcm.grc (renamed from gr-trellis/examples/grc/pccc1.grc)828
-rw-r--r--gr-trellis/examples/grc/turbo_equalization.grc2766
-rw-r--r--gr-trellis/examples/grc/viterbi_equalization.grc (renamed from gr-trellis/examples/grc/sccc1.grc)1026
-rw-r--r--gr-trellis/examples/python/CMakeLists.txt30
-rw-r--r--gr-trellis/examples/python/README10
-rw-r--r--gr-trellis/examples/python/fsm_files/awgn1o1_16rsc.fsm40
-rw-r--r--gr-trellis/examples/python/fsm_files/awgn1o1_4rsc.fsm16
-rw-r--r--gr-trellis/examples/python/fsm_files/awgn1o2_16rsc.fsm40
-rw-r--r--gr-trellis/examples/python/fsm_files/awgn1o2_4rsc.fsm14
-rw-r--r--gr-trellis/examples/python/fsm_files/awgn2o3_16ungerboeck.fsm50
-rw-r--r--gr-trellis/examples/python/fsm_files/awgn2o3_16ungerboecka.fsm48
-rw-r--r--gr-trellis/examples/python/fsm_files/awgn2o3_32ungerboeck.fsm83
-rw-r--r--gr-trellis/examples/python/fsm_files/awgn2o3_32ungerboecka.fsm84
-rw-r--r--gr-trellis/examples/python/fsm_files/awgn2o3_4_msb.fsm2
-rw-r--r--gr-trellis/examples/python/fsm_files/awgn2o3_4_msbG.fsm4
-rw-r--r--gr-trellis/examples/python/fsm_files/awgn2o3_4ungerboeck.fsm26
-rw-r--r--gr-trellis/examples/python/fsm_files/awgn2o3_4ungerboecka.fsm23
-rw-r--r--gr-trellis/examples/python/fsm_files/awgn2o3_64ungerboeck.fsm150
-rw-r--r--gr-trellis/examples/python/fsm_files/awgn2o3_64ungerboecka.fsm154
-rw-r--r--gr-trellis/examples/python/fsm_files/awgn2o3_8.fsm3
-rw-r--r--gr-trellis/examples/python/fsm_files/awgn2o3_8ungerboeck.fsm35
-rw-r--r--gr-trellis/examples/python/fsm_files/awgn2o3_8ungerboecka.fsm32
-rw-r--r--gr-trellis/examples/python/fsm_files/uncoded4.fsm7
-rwxr-xr-xgr-trellis/examples/python/test_cpm.py7
-rwxr-xr-xgr-trellis/examples/python/test_pccc_turbo1.py124
-rwxr-xr-xgr-trellis/examples/python/test_sccc_hard.py106
-rwxr-xr-xgr-trellis/examples/python/test_sccc_soft.py110
-rwxr-xr-xgr-trellis/examples/python/test_sccc_turbo.py146
-rwxr-xr-xgr-trellis/examples/python/test_sccc_turbo1.py104
-rwxr-xr-xgr-trellis/examples/python/test_sccc_turbo2.py106
-rwxr-xr-xgr-trellis/examples/python/test_tcm.py76
-rwxr-xr-xgr-trellis/examples/python/test_tcm_bit.py134
-rwxr-xr-xgr-trellis/examples/python/test_tcm_combined.py112
-rwxr-xr-xgr-trellis/examples/python/test_tcm_parallel.py118
-rwxr-xr-xgr-trellis/examples/python/test_turbo_equalization.py147
-rwxr-xr-xgr-trellis/examples/python/test_turbo_equalization1.py152
-rwxr-xr-xgr-trellis/examples/python/test_turbo_equalization2.py152
-rwxr-xr-xgr-trellis/examples/python/test_viterbi_equalization.py99
-rwxr-xr-xgr-trellis/examples/python/test_viterbi_equalization1.py108
-rw-r--r--gr-trellis/gnuradio-trellis.pc.in2
-rw-r--r--gr-trellis/grc/trellis_encoder_xx.xml26
-rw-r--r--gr-trellis/grc/trellis_metrics_x.xml3
-rw-r--r--gr-trellis/grc/trellis_pccc_decoder_combined_xx.xml2
-rw-r--r--gr-trellis/grc/trellis_permutation.xml4
-rw-r--r--gr-trellis/grc/trellis_sccc_decoder_combined_xx.xml2
-rw-r--r--gr-trellis/grc/trellis_siso_combined_f.xml16
-rw-r--r--gr-trellis/grc/trellis_siso_f.xml13
-rw-r--r--gr-trellis/grc/trellis_viterbi_combined_xx.xml8
-rw-r--r--gr-trellis/grc/trellis_viterbi_x.xml4
-rw-r--r--gr-trellis/include/gnuradio/trellis/encoder_XX.h.t6
-rw-r--r--gr-trellis/include/gnuradio/trellis/fsm.h10
-rw-r--r--gr-trellis/include/gnuradio/trellis/metrics_X.h.t5
-rw-r--r--gr-trellis/include/gnuradio/trellis/permutation.h7
-rw-r--r--gr-trellis/include/gnuradio/trellis/sccc_decoder_combined_XX.h.t1
-rw-r--r--gr-trellis/include/gnuradio/trellis/siso_combined_f.h11
-rw-r--r--gr-trellis/include/gnuradio/trellis/siso_f.h8
-rw-r--r--gr-trellis/include/gnuradio/trellis/viterbi_X.h.t13
-rw-r--r--gr-trellis/include/gnuradio/trellis/viterbi_combined_XX.h.t9
-rw-r--r--gr-trellis/lib/calc_metric.cc17
-rw-r--r--gr-trellis/lib/core_algorithms.cc47
-rw-r--r--gr-trellis/lib/encoder_XX_impl.cc.t80
-rw-r--r--gr-trellis/lib/encoder_XX_impl.h.t14
-rw-r--r--gr-trellis/lib/fsm.cc48
-rw-r--r--gr-trellis/lib/metrics_X_impl.cc.t27
-rw-r--r--gr-trellis/lib/metrics_X_impl.h.t4
-rw-r--r--gr-trellis/lib/pccc_decoder_combined_XX_impl.cc.t2
-rw-r--r--gr-trellis/lib/pccc_encoder_XX_impl.cc.t2
-rw-r--r--gr-trellis/lib/permutation_impl.cc23
-rw-r--r--gr-trellis/lib/permutation_impl.h6
-rw-r--r--gr-trellis/lib/sccc_decoder_combined_XX_impl.cc.t2
-rw-r--r--gr-trellis/lib/siso_combined_f_impl.cc109
-rw-r--r--gr-trellis/lib/siso_combined_f_impl.h12
-rw-r--r--gr-trellis/lib/siso_f_impl.cc80
-rw-r--r--gr-trellis/lib/siso_f_impl.h9
-rw-r--r--gr-trellis/lib/viterbi_X_impl.cc.t27
-rw-r--r--gr-trellis/lib/viterbi_X_impl.h.t12
-rw-r--r--gr-trellis/lib/viterbi_combined_XX_impl.cc.t45
-rw-r--r--gr-trellis/lib/viterbi_combined_XX_impl.h.t17
-rw-r--r--gr-trellis/python/trellis/CMakeLists.txt1
-rw-r--r--gr-trellis/python/trellis/__init__.py3
-rwxr-xr-xgr-trellis/python/trellis/fsm_utils.py (renamed from gr-trellis/examples/python/fsm_utils.py)61
-rw-r--r--gr-uhd/lib/usrp_sink_impl.cc15
-rw-r--r--gr-uhd/lib/usrp_source_impl.cc15
-rw-r--r--gr-utils/python/modtool/gr-newmod/cmake/Modules/FindCppUnit.cmake3
-rw-r--r--gr-utils/python/modtool/gr-newmod/cmake/Modules/GrMiscUtils.cmake321
-rw-r--r--gr-utils/python/modtool/gr-newmod/cmake/Modules/GrPlatform.cmake10
-rw-r--r--gr-utils/python/modtool/gr-newmod/cmake/Modules/GrPython.cmake25
-rw-r--r--gr-utils/python/modtool/gr-newmod/cmake/Modules/GrSwig.cmake50
-rw-r--r--gr-utils/python/modtool/gr-newmod/cmake/Modules/GrTest.cmake22
-rwxr-xr-xgr-utils/python/utils/grcc29
-rw-r--r--gr-wxgui/python/wxgui/fft_window.py6
-rw-r--r--gr-wxgui/python/wxgui/fftsink_nongl.py12
-rw-r--r--grc/CMakeLists.txt4
-rw-r--r--grc/base/FlowGraph.py20
-rw-r--r--grc/blocks/options.xml10
-rw-r--r--grc/blocks/pad_sink.xml4
-rw-r--r--grc/blocks/pad_source.xml4
-rw-r--r--grc/gui/ActionHandler.py15
-rw-r--r--grc/gui/Block.py10
-rw-r--r--grc/gui/Constants.py7
-rw-r--r--grc/gui/Messages.py8
-rw-r--r--grc/gui/Param.py5
-rw-r--r--grc/gui/Port.py8
-rw-r--r--grc/python/CMakeLists.txt1
-rw-r--r--grc/python/FlowGraph.py80
-rw-r--r--grc/python/Generator.py214
-rw-r--r--grc/python/convert_hier.py116
-rw-r--r--grc/python/flow_graph.tmpl14
-rw-r--r--volk/apps/volk_profile.cc83
-rw-r--r--volk/kernels/volk/volk_16i_32fc_dot_prod_32fc.h70
-rw-r--r--volk/kernels/volk/volk_16i_branch_4_state_8.h22
-rw-r--r--volk/kernels/volk/volk_16i_convert_8i.h65
-rw-r--r--volk/kernels/volk/volk_16i_max_star_16i.h24
-rw-r--r--volk/kernels/volk/volk_16i_max_star_horizontal_16i.h28
-rw-r--r--volk/kernels/volk/volk_16i_permute_and_scalar_add.h22
-rw-r--r--volk/kernels/volk/volk_16i_s32f_convert_32f.h182
-rw-r--r--volk/kernels/volk/volk_16i_x4_quad_max_star_16i.h22
-rw-r--r--volk/kernels/volk/volk_16i_x5_add_quad_16i_x4.h22
-rw-r--r--volk/kernels/volk/volk_16ic_deinterleave_16i_x2.h22
-rw-r--r--volk/kernels/volk/volk_16ic_deinterleave_real_16i.h22
-rw-r--r--volk/kernels/volk/volk_16ic_deinterleave_real_8i.h22
-rw-r--r--volk/kernels/volk/volk_16ic_magnitude_16i.h22
-rw-r--r--volk/kernels/volk/volk_16ic_s32f_deinterleave_32f_x2.h22
-rw-r--r--volk/kernels/volk/volk_16ic_s32f_deinterleave_real_32f.h22
-rw-r--r--volk/kernels/volk/volk_16ic_s32f_magnitude_32f.h22
-rw-r--r--volk/kernels/volk/volk_16u_byteswap.h74
-rw-r--r--volk/kernels/volk/volk_16u_byteswappuppet_16u.h55
-rw-r--r--volk/kernels/volk/volk_32f_accumulator_s32f.h22
-rw-r--r--volk/kernels/volk/volk_32f_acos_32f.h194
-rw-r--r--volk/kernels/volk/volk_32f_asin_32f.h189
-rw-r--r--volk/kernels/volk/volk_32f_atan_32f.h183
-rw-r--r--volk/kernels/volk/volk_32f_binary_slicer_32i.h22
-rw-r--r--volk/kernels/volk/volk_32f_binary_slicer_8i.h102
-rw-r--r--volk/kernels/volk/volk_32f_convert_64f.h94
-rw-r--r--volk/kernels/volk/volk_32f_cos_32f.h211
-rw-r--r--volk/kernels/volk/volk_32f_expfast_32f.h216
-rw-r--r--volk/kernels/volk/volk_32f_index_max_16u.h22
-rw-r--r--volk/kernels/volk/volk_32f_invsqrt_32f.h24
-rw-r--r--volk/kernels/volk/volk_32f_log2_32f.h332
-rw-r--r--volk/kernels/volk/volk_32f_s32f_32f_fm_detect_32f.h22
-rw-r--r--volk/kernels/volk/volk_32f_s32f_calc_spectral_noise_floor_32f.h22
-rw-r--r--volk/kernels/volk/volk_32f_s32f_convert_16i.h136
-rw-r--r--volk/kernels/volk/volk_32f_s32f_convert_32i.h22
-rw-r--r--volk/kernels/volk/volk_32f_s32f_convert_8i.h22
-rw-r--r--volk/kernels/volk/volk_32f_s32f_multiply_32f.h22
-rw-r--r--volk/kernels/volk/volk_32f_s32f_normalize.h22
-rw-r--r--volk/kernels/volk/volk_32f_s32f_power_32f.h22
-rw-r--r--volk/kernels/volk/volk_32f_s32f_stddev_32f.h22
-rw-r--r--volk/kernels/volk/volk_32f_sin_32f.h211
-rw-r--r--volk/kernels/volk/volk_32f_sqrt_32f.h22
-rw-r--r--volk/kernels/volk/volk_32f_stddev_and_mean_32f_x2.h22
-rw-r--r--volk/kernels/volk/volk_32f_tan_32f.h220
-rw-r--r--volk/kernels/volk/volk_32f_tanh_32f.h318
-rw-r--r--volk/kernels/volk/volk_32f_x2_add_32f.h24
-rw-r--r--volk/kernels/volk/volk_32f_x2_divide_32f.h22
-rw-r--r--volk/kernels/volk/volk_32f_x2_dot_prod_16i.h22
-rw-r--r--volk/kernels/volk/volk_32f_x2_dot_prod_32f.h22
-rw-r--r--volk/kernels/volk/volk_32f_x2_interleave_32fc.h24
-rw-r--r--volk/kernels/volk/volk_32f_x2_max_32f.h24
-rw-r--r--volk/kernels/volk/volk_32f_x2_min_32f.h22
-rw-r--r--volk/kernels/volk/volk_32f_x2_multiply_32f.h22
-rw-r--r--volk/kernels/volk/volk_32f_x2_pow_32f.h298
-rw-r--r--volk/kernels/volk/volk_32f_x2_s32f_interleave_16ic.h22
-rw-r--r--volk/kernels/volk/volk_32f_x2_subtract_32f.h22
-rw-r--r--volk/kernels/volk/volk_32f_x3_sum_of_poly_32f.h22
-rw-r--r--volk/kernels/volk/volk_32fc_32f_dot_prod_32fc.h30
-rw-r--r--volk/kernels/volk/volk_32fc_32f_multiply_32fc.h22
-rw-r--r--volk/kernels/volk/volk_32fc_conjugate_32fc.h98
-rw-r--r--volk/kernels/volk/volk_32fc_deinterleave_32f_x2.h104
-rw-r--r--volk/kernels/volk/volk_32fc_deinterleave_64f_x2.h124
-rw-r--r--volk/kernels/volk/volk_32fc_deinterleave_imag_32f.h93
-rw-r--r--volk/kernels/volk/volk_32fc_deinterleave_real_32f.h48
-rw-r--r--volk/kernels/volk/volk_32fc_deinterleave_real_64f.h22
-rw-r--r--volk/kernels/volk/volk_32fc_index_max_16u.h22
-rw-r--r--volk/kernels/volk/volk_32fc_magnitude_32f.h114
-rw-r--r--volk/kernels/volk/volk_32fc_magnitude_squared_32f.h110
-rw-r--r--volk/kernels/volk/volk_32fc_s32f_atan2_32f.h22
-rw-r--r--volk/kernels/volk/volk_32fc_s32f_deinterleave_real_16i.h22
-rw-r--r--volk/kernels/volk/volk_32fc_s32f_magnitude_16i.h22
-rw-r--r--volk/kernels/volk/volk_32fc_s32f_power_32fc.h22
-rw-r--r--volk/kernels/volk/volk_32fc_s32f_power_spectrum_32f.h22
-rw-r--r--volk/kernels/volk/volk_32fc_s32f_x2_power_spectral_density_32f.h114
-rw-r--r--volk/kernels/volk/volk_32fc_s32fc_multiply_32fc.h155
-rw-r--r--volk/kernels/volk/volk_32fc_s32fc_rotatorpuppet_32fc.h22
-rw-r--r--volk/kernels/volk/volk_32fc_s32fc_x2_rotator_32fc.h22
-rw-r--r--volk/kernels/volk/volk_32fc_x2_conjugate_dot_prod_32fc.h71
-rw-r--r--volk/kernels/volk/volk_32fc_x2_dot_prod_32fc.h139
-rw-r--r--volk/kernels/volk/volk_32fc_x2_multiply_32fc.h120
-rw-r--r--volk/kernels/volk/volk_32fc_x2_multiply_conjugate_32fc.h128
-rw-r--r--volk/kernels/volk/volk_32fc_x2_s32f_square_dist_scalar_mult_32f.h22
-rw-r--r--volk/kernels/volk/volk_32fc_x2_square_dist_32f.h22
-rw-r--r--volk/kernels/volk/volk_32i_s32f_convert_32f.h22
-rw-r--r--volk/kernels/volk/volk_32i_x2_and_32i.h56
-rw-r--r--volk/kernels/volk/volk_32i_x2_or_32i.h56
-rw-r--r--volk/kernels/volk/volk_32u_byteswap.h77
-rw-r--r--volk/kernels/volk/volk_32u_byteswappuppet_32u.h45
-rw-r--r--volk/kernels/volk/volk_32u_popcnt.h22
-rw-r--r--volk/kernels/volk/volk_32u_popcntpuppet_32u.h47
-rw-r--r--volk/kernels/volk/volk_64f_convert_32f.h22
-rw-r--r--volk/kernels/volk/volk_64f_x2_max_64f.h22
-rw-r--r--volk/kernels/volk/volk_64f_x2_min_64f.h22
-rw-r--r--volk/kernels/volk/volk_64u_byteswap.h77
-rw-r--r--volk/kernels/volk/volk_64u_byteswappuppet_64u.h45
-rw-r--r--volk/kernels/volk/volk_64u_popcnt.h42
-rw-r--r--volk/kernels/volk/volk_64u_popcntpuppet_64u.h48
-rw-r--r--volk/kernels/volk/volk_8i_convert_16i.h22
-rw-r--r--volk/kernels/volk/volk_8i_s32f_convert_32f.h22
-rw-r--r--volk/kernels/volk/volk_8ic_deinterleave_16i_x2.h103
-rw-r--r--volk/kernels/volk/volk_8ic_deinterleave_real_16i.h70
-rw-r--r--volk/kernels/volk/volk_8ic_deinterleave_real_8i.h80
-rw-r--r--volk/kernels/volk/volk_8ic_s32f_deinterleave_32f_x2.h22
-rw-r--r--volk/kernels/volk/volk_8ic_s32f_deinterleave_real_32f.h22
-rw-r--r--volk/kernels/volk/volk_8ic_x2_multiply_conjugate_16ic.h22
-rw-r--r--volk/kernels/volk/volk_8ic_x2_s32f_multiply_conjugate_32fc.h22
-rw-r--r--volk/kernels/volk/volk_8u_conv_k7_r2puppet_8u.h22
-rw-r--r--volk/kernels/volk/volk_8u_x4_conv_k7_r2_8u.h22
-rw-r--r--volk/lib/CMakeLists.txt15
-rw-r--r--volk/lib/qa_utils.cc34
-rw-r--r--volk/lib/qa_utils.h43
-rw-r--r--volk/lib/testqa.cc14
319 files changed, 17530 insertions, 5968 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7f617df901..858a7d6a2f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -46,8 +46,8 @@ message(STATUS "Build type set to ${CMAKE_BUILD_TYPE}.")
# Set the version information here
set(VERSION_INFO_MAJOR_VERSION 3)
set(VERSION_INFO_API_COMPAT 7)
-set(VERSION_INFO_MINOR_VERSION 5)
-set(VERSION_INFO_MAINT_VERSION 1)
+set(VERSION_INFO_MINOR_VERSION 6)
+set(VERSION_INFO_MAINT_VERSION git)
include(GrVersion) #setup version info
# Append -O2 optimization flag for Debug builds
diff --git a/cmake/Modules/FindUHD.cmake b/cmake/Modules/FindUHD.cmake
index cfb89b11ce..21cb0942c3 100644
--- a/cmake/Modules/FindUHD.cmake
+++ b/cmake/Modules/FindUHD.cmake
@@ -2,7 +2,7 @@
# Find the library for the USRP Hardware Driver
########################################################################
-# make this file non-reentrant
+# make this file non-reentrant within the current context
if(__INCLUDED_FIND_UHD_CMAKE)
return()
endif()
@@ -20,6 +20,12 @@ unset(CMAKE_MODULE_PATH)
# handle REQUIRED internally later
unset(UHD_FOUND)
+# set that UHDConfig.cmake was not used. Have to use the ENV, since
+# UHDConfigVersion does not allow CACHE changes and UHDConfig might
+# not allow CACHE changes.
+set(ENV{UHD_CONFIG_USED} FALSE)
+set(ENV{UHD_CONFIG_VERSION_USED} FALSE)
+
# was the version specified?
unset(LOCAL_UHD_FIND_VERSION)
if(UHD_FIND_VERSION)
@@ -42,10 +48,10 @@ find_package(
# restore CMAKE_MODULE_PATH
set(CMAKE_MODULE_PATH ${SAVED_CMAKE_MODULE_PATH})
-# check if UHD was found above
-if(NOT UHD_FOUND)
+# check if UHDConfig was used above
+if(NOT $ENV{UHD_CONFIG_VERSION_USED})
- # Not found; try the "old" method (not as robust)
+ # Not used; try the "old" method (not as robust)
include(FindPkgConfig)
pkg_check_modules(PC_UHD uhd)
@@ -67,7 +73,7 @@ if(NOT UHD_FOUND)
PATHS /usr/local/lib
/usr/lib
)
-endif(NOT UHD_FOUND)
+endif(NOT $ENV{UHD_CONFIG_VERSION_USED})
if(UHD_LIBRARIES AND UHD_INCLUDE_DIRS)
@@ -79,7 +85,9 @@ if(UHD_LIBRARIES AND UHD_INCLUDE_DIRS)
mark_as_advanced(UHD_LIBRARIES UHD_INCLUDE_DIRS)
elseif(UHD_FIND_REQUIRED)
-
- message(FATAL_ERROR "UHD is required, but was not found.")
-
+ if($ENV{UHD_CONFIG_VERSION_USED} AND NOT $ENV{UHD_CONFIG_USED})
+ message(FATAL_ERROR "The found UHD version ($ENV{UHD_PACKAGE_VERSION}) is not compatible with the version required (${UHD_FIND_VERSION}).")
+ else()
+ message(FATAL_ERROR "UHD is required, but was not found.")
+ endif()
endif()
diff --git a/docs/doxygen/Doxyfile.in b/docs/doxygen/Doxyfile.in
index 3b82e2c40c..3f558526e7 100644
--- a/docs/doxygen/Doxyfile.in
+++ b/docs/doxygen/Doxyfile.in
@@ -142,26 +142,51 @@ STRIP_FROM_PATH =
# are normally passed to the compiler using the -I flag.
STRIP_FROM_INC_PATH = @CMAKE_SOURCE_DIR@/gnuradio-runtime/include \
+ @CMAKE_BINARY_DIR@/gnuradio-runtime/include \
@CMAKE_SOURCE_DIR@/gr-analog/include \
+ @CMAKE_BINARY_DIR@/gr-analog/include \
@CMAKE_SOURCE_DIR@/gr-atsc/include \
+ @CMAKE_BINARY_DIR@/gr-atsc/include \
@CMAKE_SOURCE_DIR@/gr-audio/include \
+ @CMAKE_BINARY_DIR@/gr-audio/include \
@CMAKE_SOURCE_DIR@/gr-blocks/include \
+ @CMAKE_BINARY_DIR@/gr-blocks/include \
@CMAKE_SOURCE_DIR@/gr-channels/include \
+ @CMAKE_BINARY_DIR@/gr-channels/include \
@CMAKE_SOURCE_DIR@/gr-comedi/include \
+ @CMAKE_BINARY_DIR@/gr-comedi/include \
@CMAKE_SOURCE_DIR@/gr-digital/include \
+ @CMAKE_BINARY_DIR@/gr-digital/include \
+ @CMAKE_SOURCE_DIR@/gr-dtv/include \
+ @CMAKE_BINARY_DIR@/gr-dtv/include \
@CMAKE_SOURCE_DIR@/gr-fcd/include \
+ @CMAKE_BINARY_DIR@/gr-fcd/include \
@CMAKE_SOURCE_DIR@/gr-fec/include \
+ @CMAKE_BINARY_DIR@/gr-fec/include \
@CMAKE_SOURCE_DIR@/gr-fft/include \
+ @CMAKE_BINARY_DIR@/gr-fft/include \
@CMAKE_SOURCE_DIR@/gr-filter/include \
+ @CMAKE_BINARY_DIR@/gr-filter/include \
@CMAKE_SOURCE_DIR@/gr-noaa/include \
+ @CMAKE_BINARY_DIR@/gr-noaa/include \
@CMAKE_SOURCE_DIR@/gr-pager/include \
+ @CMAKE_BINARY_DIR@/gr-pager/include \
@CMAKE_SOURCE_DIR@/gr-qtgui/include \
+ @CMAKE_BINARY_DIR@/gr-qtgui/include \
@CMAKE_SOURCE_DIR@/gr-trellis/include \
+ @CMAKE_BINARY_DIR@/gr-trellis/include \
@CMAKE_SOURCE_DIR@/gr-uhd/include \
+ @CMAKE_BINARY_DIR@/gr-uhd/include \
@CMAKE_SOURCE_DIR@/gr-video-sdl/include \
+ @CMAKE_BINARY_DIR@/gr-video-sdl/include \
@CMAKE_SOURCE_DIR@/gr-vocoder/include \
+ @CMAKE_BINARY_DIR@/gr-vocoder/include \
+ @CMAKE_SOURCE_DIR@/gr-wavelet/include \
+ @CMAKE_BINARY_DIR@/gr-wavelet/include \
@CMAKE_SOURCE_DIR@/gr-wxgui/include \
- @CMAKE_SOURCE_DIR@/volk/include
+ @CMAKE_BINARY_DIR@/gr-wxgui/include \
+ @CMAKE_SOURCE_DIR@/volk/include \
+ @CMAKE_BINARY_DIR@/volk/include
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
# (but less readable) file names. This can be useful if your file system
diff --git a/docs/doxygen/other/pmt.dox b/docs/doxygen/other/pmt.dox
index bc7f870ccd..51e1865d39 100644
--- a/docs/doxygen/other/pmt.dox
+++ b/docs/doxygen/other/pmt.dox
@@ -477,4 +477,21 @@ pmt::pmt_t a pmt::from_double(1.0);
std::cout << "The PMT a contains " << a << std::endl;
\endcode
+
+\section pmt_python Conversion between Python Objects and PMTs
+
+Although PMTs can be manipulated in Python using the Python versions
+of the C++ interfaces, there are some additional goodies that make it
+easier to work with PMTs in python. There are functions to automate
+the conversion between PMTs and Python types for booleans, strings,
+integers, longs, floats, complex numbers, dictionaries, lists, tuples
+and combinations thereof.
+
+Two functions capture most of this functionality:
+
+\code
+pmt.to_pmt # Converts a python object to a PMT.
+pmt.to_python # Converts a PMT into a python object.
+\endcode
+
*/
diff --git a/docs/doxygen/other/stream_tags.dox b/docs/doxygen/other/stream_tags.dox
index 851740984e..d48ec1ddee 100644
--- a/docs/doxygen/other/stream_tags.dox
+++ b/docs/doxygen/other/stream_tags.dox
@@ -61,7 +61,10 @@ at <em>nitems_written(0)+i</em> for the 0th output port.
\section stream_tags_api Stream Tags API
The stream tags API consists of four functions, two to add and two to
-get the stream tags. These functions are:
+get the stream tags. These functions are only meant to be accessed
+within a call to general_work/work. While they can be called elsewhere
+in time by a block, the behavior outside of work is undefined without
+exact knowledge of the item counts in the buffers.
\li gr::block::add_item_tag: Adds an item tag to a particular output port using a
gr::tag_t data type.
diff --git a/gnuradio-runtime/include/gnuradio/block.h b/gnuradio-runtime/include/gnuradio/block.h
index a033e0ac27..4a534b7f46 100644
--- a/gnuradio-runtime/include/gnuradio/block.h
+++ b/gnuradio-runtime/include/gnuradio/block.h
@@ -221,7 +221,8 @@ namespace gr {
/*!
* \brief Tell the scheduler \p how_many_items of input stream \p
- * which_input were consumed.
+ * which_input were consumed.
+ * This function should be called at the end of work() or general_work(), after all processing is finished.
*/
void consume(int which_input, int how_many_items);
@@ -503,6 +504,11 @@ namespace gr {
float pc_work_time_total();
/*!
+ * \brief Gets average throughput.
+ */
+ float pc_throughput_avg();
+
+ /*!
* \brief Resets the performance counters
*/
void reset_perf_counters();
@@ -636,7 +642,7 @@ namespace gr {
void add_item_tag(unsigned int which_output, const tag_t &tag);
/*!
- * \brief Removes a tag from the given input buffer.
+ * \brief DEPRECATED. Will be removed in 3.8.
*
* \param which_input an integer of which input stream to remove the tag from
* \param abs_offset a uint64 number of the absolute item number
@@ -662,9 +668,7 @@ namespace gr {
}
/*!
- * \brief Removes a tag from the given input buffer.
- *
- * If no such tag is found, does nothing.
+ * \brief DEPRECATED. Will be removed in 3.8.
*
* \param which_input an integer of which input stream to remove the tag from
* \param tag the tag object to remove
diff --git a/gnuradio-runtime/include/gnuradio/block_detail.h b/gnuradio-runtime/include/gnuradio/block_detail.h
index 41568c8ab3..916c0a46c1 100644
--- a/gnuradio-runtime/include/gnuradio/block_detail.h
+++ b/gnuradio-runtime/include/gnuradio/block_detail.h
@@ -219,6 +219,7 @@ namespace gr {
float pc_output_buffers_full_avg(size_t which);
std::vector<float> pc_output_buffers_full_avg();
float pc_work_time_avg();
+ float pc_throughput_avg();
float pc_noutput_items_var();
float pc_nproduced_var();
@@ -246,6 +247,9 @@ namespace gr {
float d_ins_noutput_items;
float d_avg_noutput_items;
float d_var_noutput_items;
+ float d_total_noutput_items;
+ gr::high_res_timer_type d_pc_start_time;
+ gr::high_res_timer_type d_pc_last_work_time;
float d_ins_nproduced;
float d_avg_nproduced;
float d_var_nproduced;
@@ -260,6 +264,7 @@ namespace gr {
float d_avg_work_time;
float d_var_work_time;
float d_total_work_time;
+ float d_avg_throughput;
float d_pc_counter;
block_detail(unsigned int ninputs, unsigned int noutputs);
diff --git a/gnuradio-runtime/include/gnuradio/buffer.h b/gnuradio-runtime/include/gnuradio/buffer.h
index e2d5760e59..c0c9f3d39d 100644
--- a/gnuradio-runtime/include/gnuradio/buffer.h
+++ b/gnuradio-runtime/include/gnuradio/buffer.h
@@ -28,7 +28,7 @@
#include <gnuradio/tags.h>
#include <boost/weak_ptr.hpp>
#include <gnuradio/thread/thread.h>
-#include <deque>
+#include <map>
namespace gr {
@@ -125,8 +125,10 @@ namespace gr {
*/
void prune_tags(uint64_t max_time);
- std::deque<tag_t>::iterator get_tags_begin() { return d_item_tags.begin(); }
- std::deque<tag_t>::iterator get_tags_end() { return d_item_tags.end(); }
+ std::multimap<uint64_t,tag_t>::iterator get_tags_begin() { return d_item_tags.begin(); }
+ std::multimap<uint64_t,tag_t>::iterator get_tags_end() { return d_item_tags.end(); }
+ std::multimap<uint64_t,tag_t>::iterator get_tags_lower_bound(uint64_t x) { return d_item_tags.lower_bound(x); }
+ std::multimap<uint64_t,tag_t>::iterator get_tags_upper_bound(uint64_t x) { return d_item_tags.upper_bound(x); }
// -------------------------------------------------------------------------
@@ -157,7 +159,7 @@ namespace gr {
unsigned int d_write_index; // in items [0,d_bufsize)
uint64_t d_abs_write_offset; // num items written since the start
bool d_done;
- std::deque<tag_t> d_item_tags;
+ std::multimap<uint64_t,tag_t> d_item_tags;
uint64_t d_last_min_items_read;
unsigned index_add(unsigned a, unsigned b)
diff --git a/gnuradio-runtime/include/gnuradio/logger.h.in b/gnuradio-runtime/include/gnuradio/logger.h.in
index 05367a1873..941ce75af3 100644
--- a/gnuradio-runtime/include/gnuradio/logger.h.in
+++ b/gnuradio-runtime/include/gnuradio/logger.h.in
@@ -844,8 +844,11 @@ namespace gr {
* block, we use 'alias()' for this value, and this is set up for us
* automatically in gr::block.
*/
- GR_RUNTIME_API bool configure_default_loggers(gr::logger_ptr &l, gr::logger_ptr &d,
- const std::string name);
+ GR_RUNTIME_API bool configure_default_loggers(gr::logger_ptr &l, gr::logger_ptr &d,
+ const std::string name);
+
+ GR_RUNTIME_API bool update_logger_alias(const std::string &name, const std::string &alias);
+
} /* namespace gr */
diff --git a/gnuradio-runtime/include/gnuradio/tagged_stream_block.h b/gnuradio-runtime/include/gnuradio/tagged_stream_block.h
index 1fe92ee25a..86343f281d 100644
--- a/gnuradio-runtime/include/gnuradio/tagged_stream_block.h
+++ b/gnuradio-runtime/include/gnuradio/tagged_stream_block.h
@@ -97,6 +97,8 @@ namespace gr {
*/
void /* final */ forecast (int noutput_items, gr_vector_int &ninput_items_required);
+ bool check_topology(int ninputs, int /* noutputs */);
+
/*!
* - Reads the number of input items from the tags using parse_length_tags()
* - Checks there's enough data on the input and output buffers
diff --git a/gnuradio-runtime/include/pmt/pmt.h b/gnuradio-runtime/include/pmt/pmt.h
index 3e17571b23..cb6fdf44d5 100644
--- a/gnuradio-runtime/include/pmt/pmt.h
+++ b/gnuradio-runtime/include/pmt/pmt.h
@@ -201,6 +201,7 @@ PMT_API bool is_real(pmt_t obj);
//! Return the pmt value that represents double \p x.
PMT_API pmt_t from_double(double x);
+PMT_API pmt_t from_float(float x);
/*!
* \brief Convert pmt to double if possible.
@@ -211,6 +212,15 @@ PMT_API pmt_t from_double(double x);
*/
PMT_API double to_double(pmt_t x);
+/*!
+ * \brief Convert pmt to float if possible.
+ *
+ * This basically is to_double() with a type-cast; the PMT stores
+ * the value as a double in any case. Use this when strict typing
+ * is required.
+ */
+PMT_API float to_float(pmt_t x);
+
/*
* ------------------------------------------------------------------------
* Complex
diff --git a/gnuradio-runtime/lib/basic_block.cc b/gnuradio-runtime/lib/basic_block.cc
index 686c1d6e65..09d2eb2b3a 100644
--- a/gnuradio-runtime/lib/basic_block.cc
+++ b/gnuradio-runtime/lib/basic_block.cc
@@ -26,6 +26,7 @@
#include <gnuradio/basic_block.h>
#include <gnuradio/block_registry.h>
+#include <gnuradio/logger.h>
#include <stdexcept>
#include <sstream>
#include <iostream>
@@ -82,6 +83,7 @@ namespace gr {
// set the block's alias
d_symbol_alias = name;
+ update_logger_alias(symbol_name(), d_symbol_alias);
}
// ** Message passing interface **
diff --git a/gnuradio-runtime/lib/block.cc b/gnuradio-runtime/lib/block.cc
index a15fb89c85..9173094e53 100644
--- a/gnuradio-runtime/lib/block.cc
+++ b/gnuradio-runtime/lib/block.cc
@@ -60,7 +60,7 @@ namespace gr {
message_port_register_in(pmt::mp("system"));
set_msg_handler(pmt::mp("system"), boost::bind(&block::system_handler, this, _1));
- configure_default_loggers(d_logger, d_debug_logger, alias());
+ configure_default_loggers(d_logger, d_debug_logger, symbol_name());
}
block::~block()
@@ -682,6 +682,16 @@ namespace gr {
}
}
+ float
+ block::pc_throughput_avg() {
+ if(d_detail) {
+ return d_detail->pc_throughput_avg();
+ }
+ else {
+ return 0;
+ }
+ }
+
void
block::reset_perf_counters()
{
diff --git a/gnuradio-runtime/lib/block_detail.cc b/gnuradio-runtime/lib/block_detail.cc
index 77c457cf7f..9463e8d13b 100644
--- a/gnuradio-runtime/lib/block_detail.cc
+++ b/gnuradio-runtime/lib/block_detail.cc
@@ -46,6 +46,7 @@ namespace gr {
d_ins_noutput_items(0),
d_avg_noutput_items(0),
d_var_noutput_items(0),
+ d_total_noutput_items(0),
d_ins_nproduced(0),
d_avg_nproduced(0),
d_var_nproduced(0),
@@ -58,9 +59,11 @@ namespace gr {
d_ins_work_time(0),
d_avg_work_time(0),
d_var_work_time(0),
+ d_avg_throughput(0),
d_pc_counter(0)
{
s_ncurrently_allocated++;
+ d_pc_start_time = gr::high_res_timer_now();
}
block_detail::~block_detail()
@@ -279,6 +282,8 @@ namespace gr {
d_ins_noutput_items = noutput_items;
d_avg_noutput_items = noutput_items;
d_var_noutput_items = 0;
+ d_total_noutput_items = noutput_items;
+ d_pc_start_time = (float)gr::high_res_timer_now();
for(size_t i=0; i < d_input.size(); i++) {
gr::thread::scoped_lock guard(*d_input[i]->mutex());
float pfull = static_cast<float>(d_input[i]->items_available()) /
@@ -312,6 +317,10 @@ namespace gr {
d_ins_noutput_items = noutput_items;
d_avg_noutput_items = d_avg_noutput_items + d/d_pc_counter;
d_var_noutput_items = d_var_noutput_items + d*d;
+ d_total_noutput_items += noutput_items;
+ d_pc_last_work_time = gr::high_res_timer_now();
+ float monitor_time = (float)(d_pc_last_work_time - d_pc_start_time) / (float)gr::high_res_timer_tps();
+ d_avg_throughput = d_total_noutput_items / monitor_time;
for(size_t i=0; i < d_input.size(); i++) {
gr::thread::scoped_lock guard(*d_input[i]->mutex());
@@ -501,4 +510,8 @@ namespace gr {
return d_total_work_time;
}
+ float
+ block_detail::pc_throughput_avg() {
+ return d_avg_throughput;
+ }
} /* namespace gr */
diff --git a/gnuradio-runtime/lib/buffer.cc b/gnuradio-runtime/lib/buffer.cc
index 162324e590..f00e9a04bf 100644
--- a/gnuradio-runtime/lib/buffer.cc
+++ b/gnuradio-runtime/lib/buffer.cc
@@ -23,7 +23,7 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-
+#include <algorithm>
#include <gnuradio/buffer.h>
#include <gnuradio/math.h>
#include "vmcircbuf.h"
@@ -225,16 +225,16 @@ namespace gr {
buffer::add_item_tag(const tag_t &tag)
{
gr::thread::scoped_lock guard(*mutex());
- d_item_tags.push_back(tag);
+ d_item_tags.insert(std::pair<uint64_t,tag_t>(tag.offset,tag));
}
void
buffer::remove_item_tag(const tag_t &tag, long id)
{
gr::thread::scoped_lock guard(*mutex());
- for(std::deque<tag_t>::iterator it = d_item_tags.begin(); it != d_item_tags.end(); ++it) {
- if(*it == tag) {
- (*it).marked_deleted.push_back(id);
+ for(std::multimap<uint64_t,tag_t>::iterator it = d_item_tags.lower_bound(tag.offset); it != d_item_tags.upper_bound(tag.offset); ++it) {
+ if((*it).second == tag) {
+ (*it).second.marked_deleted.push_back(id);
}
}
}
@@ -250,25 +250,9 @@ namespace gr {
If this function is used elsewhere, remember to lock the
buffer's mutex al la the scoped_lock line below.
*/
- //gr::thread::scoped_lock guard(*mutex());
- std::deque<tag_t>::iterator itr = d_item_tags.begin();
-
- uint64_t item_time;
-
- // Since tags are not guarenteed to be in any particular order, we
- // need to erase here instead of pop_front. An erase in the middle
- // invalidates all iterators; so this resets the iterator to find
- // more. Mostly, we wil be erasing from the front and
- // therefore lose little time this way.
- while(itr != d_item_tags.end()) {
- item_time = (*itr).offset;
- if(item_time+d_max_reader_delay + bufsize() < max_time) {
- d_item_tags.erase(itr);
- itr = d_item_tags.begin();
- }
- else
- itr++;
- }
+ std::multimap<uint64_t, tag_t>::iterator end_itr = d_item_tags.lower_bound(max_time);
+ std::multimap<uint64_t, tag_t>::iterator begin_itr = d_item_tags.begin();
+ d_item_tags.erase(begin_itr, end_itr);
}
long
@@ -333,30 +317,28 @@ namespace gr {
buffer_reader::get_tags_in_range(std::vector<tag_t> &v,
uint64_t abs_start,
uint64_t abs_end,
- long id)
+ long id)
{
gr::thread::scoped_lock guard(*mutex());
v.resize(0);
- std::deque<tag_t>::iterator itr = d_buffer->get_tags_begin();
+ std::multimap<uint64_t,tag_t>::iterator itr = d_buffer->get_tags_lower_bound(abs_start);
+ std::multimap<uint64_t,tag_t>::iterator itr_end = d_buffer->get_tags_upper_bound(abs_end);
uint64_t item_time;
- while(itr != d_buffer->get_tags_end()) {
- item_time = (*itr).offset + d_attr_delay;
-
+ while(itr != itr_end) {
+ item_time = (*itr).second.offset + d_attr_delay;
if((item_time >= abs_start) && (item_time < abs_end)) {
- std::vector<long>::iterator id_itr;
- id_itr = std::find(itr->marked_deleted.begin(), itr->marked_deleted.end(), id);
-
+ std::vector<long>::iterator id_itr;
+ id_itr = std::find(itr->second.marked_deleted.begin(), itr->second.marked_deleted.end(), id);
// If id is not in the vector of marked blocks
- if(id_itr == itr->marked_deleted.end()) {
- tag_t t = *itr;
+ if(id_itr == itr->second.marked_deleted.end()) {
+ tag_t t = (*itr).second;
t.offset += d_attr_delay;
- v.push_back(t);
- v.back().marked_deleted.clear();
- }
+ v.push_back(t);
+ v.back().marked_deleted.clear();
+ }
}
-
itr++;
}
}
diff --git a/gnuradio-runtime/lib/logger.cc b/gnuradio-runtime/lib/logger.cc
index bb1d4b4c33..13c8391c8e 100644
--- a/gnuradio-runtime/lib/logger.cc
+++ b/gnuradio-runtime/lib/logger.cc
@@ -417,4 +417,35 @@ namespace gr {
return false;
}
+ bool
+ update_logger_alias(const std::string &name, const std::string &alias)
+ {
+#ifdef ENABLE_GR_LOG
+#ifdef HAVE_LOG4CPP
+ prefs *p = prefs::singleton();
+ std::string log_file = p->get_string("LOG", "log_file", "");
+ std::string debug_file = p->get_string("LOG", "debug_file", "");
+
+ GR_LOG_GETLOGGER(LOG, "gr_log." + name);
+ if(log_file.size() > 0) {
+ if(log_file == "stdout") {
+ boost::format str("gr::log :%%p: %1% - %%m%%n");
+ GR_LOG_SET_CONSOLE_APPENDER(LOG, "cout", boost::str(str % alias));
+ }
+ else if(log_file == "stderr") {
+ boost::format str("gr::log :%%p: %1% - %%m%%n");
+ GR_LOG_SET_CONSOLE_APPENDER(LOG, "cerr", boost::str(str % alias));
+ }
+ else {
+ boost::format str("%%r :%%p: %1% - %%m%%n");
+ GR_LOG_SET_FILE_APPENDER(LOG, log_file, true, boost::str(str % alias));
+ }
+ }
+ return true;
+#endif /* HAVE_LOG4CPP */
+#endif /* ENABLE_GR_LOG */
+
+ return false;
+ }
+
} /* namespace gr */
diff --git a/gnuradio-runtime/lib/pmt/pmt.cc b/gnuradio-runtime/lib/pmt/pmt.cc
index 082b98a80d..da830e1aed 100644
--- a/gnuradio-runtime/lib/pmt/pmt.cc
+++ b/gnuradio-runtime/lib/pmt/pmt.cc
@@ -368,6 +368,12 @@ from_double(double x)
return pmt_t(new pmt_real(x));
}
+pmt_t
+from_float(float x)
+{
+ return pmt_t(new pmt_real(x));
+}
+
double
to_double(pmt_t x)
{
@@ -379,6 +385,12 @@ to_double(pmt_t x)
throw wrong_type("pmt_to_double", x);
}
+float
+to_float(pmt_t x)
+{
+ return float(to_double(x));
+}
+
////////////////////////////////////////////////////////////////////////////
// Complex
////////////////////////////////////////////////////////////////////////////
diff --git a/gnuradio-runtime/lib/pmt/qa_pmt_prims.cc b/gnuradio-runtime/lib/pmt/qa_pmt_prims.cc
index 2f46b014db..2b3ca32293 100644
--- a/gnuradio-runtime/lib/pmt/qa_pmt_prims.cc
+++ b/gnuradio-runtime/lib/pmt/qa_pmt_prims.cc
@@ -125,6 +125,15 @@ qa_pmt_prims::test_reals()
CPPUNIT_ASSERT_EQUAL(-1.0, pmt::to_double(m1));
CPPUNIT_ASSERT_EQUAL(1.0, pmt::to_double(p1));
CPPUNIT_ASSERT_EQUAL(1.0, pmt::to_double(pmt::from_long(1)));
+
+ pmt::pmt_t p2 = pmt::from_float(1);
+ pmt::pmt_t m2 = pmt::from_float(-1);
+ CPPUNIT_ASSERT(pmt::is_real(p2));
+ CPPUNIT_ASSERT(pmt::is_real(m2));
+ CPPUNIT_ASSERT_THROW(pmt::to_float(pmt::PMT_T), pmt::wrong_type);
+ CPPUNIT_ASSERT_EQUAL(float(-1.0), pmt::to_float(m2));
+ CPPUNIT_ASSERT_EQUAL(float(1.0), pmt::to_float(p2));
+ CPPUNIT_ASSERT_EQUAL(float(1.0), pmt::to_float(pmt::from_long(1)));
}
void
diff --git a/gnuradio-runtime/lib/tagged_stream_block.cc b/gnuradio-runtime/lib/tagged_stream_block.cc
index c6d5fc1fec..252a235fbf 100644
--- a/gnuradio-runtime/lib/tagged_stream_block.cc
+++ b/gnuradio-runtime/lib/tagged_stream_block.cc
@@ -89,6 +89,14 @@ namespace gr {
return;
}
+ bool
+ tagged_stream_block::check_topology(int ninputs, int /* noutputs */)
+ {
+ d_n_input_items_reqd.resize(ninputs, 0);
+ return true;
+ }
+
+
int
tagged_stream_block::general_work(int noutput_items,
gr_vector_int &ninput_items,
@@ -99,7 +107,9 @@ namespace gr {
return work(noutput_items, ninput_items, input_items, output_items);
}
- if(d_n_input_items_reqd[0] == 0) { // Otherwise, it's already set from a previous call
+ // Read TSB tags, unless we...
+ // ...don't have inputs or ... ... we already set it in a previous run.
+ if(!d_n_input_items_reqd.empty() && d_n_input_items_reqd[0] == 0) {
std::vector<std::vector<tag_t> > tags(input_items.size(), std::vector<tag_t>());
for(unsigned i = 0; i < input_items.size(); i++) {
get_tags_in_range(tags[i], i, nitems_read(i), nitems_read(i)+1);
diff --git a/gnuradio-runtime/python/gnuradio/gr/tag_utils.py b/gnuradio-runtime/python/gnuradio/gr/tag_utils.py
index cbca9d44ae..ba46e3f4d9 100644
--- a/gnuradio-runtime/python/gnuradio/gr/tag_utils.py
+++ b/gnuradio-runtime/python/gnuradio/gr/tag_utils.py
@@ -89,9 +89,22 @@ def python_to_tag(tag_struct):
tag.srcid = tag_struct[3]
good = True
+ elif(len(tag_struct) == 3):
+ if(isinstance(tag_struct[0], (int,long))):
+ tag.offset = tag_struct[0]
+ good = True
+
+ if(isinstance(tag_struct[1], pmt.pmt_swig.swig_int_ptr)):
+ tag.key = tag_struct[1]
+ good = True
+
+ if(isinstance(tag_struct[2], pmt.pmt_swig.swig_int_ptr)):
+ tag.value = tag_struct[2]
+ good = True
+
+ tag.srcid = pmt.PMT_F
+
if(good):
return tag
else:
return None
-
-
diff --git a/gnuradio-runtime/python/pmt/qa_pmt.py b/gnuradio-runtime/python/pmt/qa_pmt.py
index 5c1af2c00e..32cff62f44 100755
--- a/gnuradio-runtime/python/pmt/qa_pmt.py
+++ b/gnuradio-runtime/python/pmt/qa_pmt.py
@@ -36,7 +36,9 @@ class test_pmt(unittest.TestCase):
const = 123765
x_pmt = pmt.from_double(const)
x_int = pmt.to_double(x_pmt)
+ x_float = pmt.to_float(x_pmt)
self.assertEqual(x_int, const)
+ self.assertEqual(x_float, const)
def test03(self):
v = pmt.init_f32vector(3, [11, -22, 33])
diff --git a/gnuradio-runtime/swig/block.i b/gnuradio-runtime/swig/block.i
index 9f3f374d78..945cea79b2 100644
--- a/gnuradio-runtime/swig/block.i
+++ b/gnuradio-runtime/swig/block.i
@@ -96,6 +96,7 @@ class gr::block : public gr::basic_block
float pc_work_time_avg();
float pc_work_time_var();
float pc_work_time_total();
+ float pc_throughput_avg();
// Methods to manage processor affinity.
void set_processor_affinity(const std::vector<int> &mask);
diff --git a/gnuradio-runtime/swig/pmt_swig.i b/gnuradio-runtime/swig/pmt_swig.i
index e54b544977..c4b678222d 100644
--- a/gnuradio-runtime/swig/pmt_swig.i
+++ b/gnuradio-runtime/swig/pmt_swig.i
@@ -111,6 +111,8 @@ namespace pmt{
bool is_real(pmt_t obj);
pmt_t from_double(double x);
double to_double(pmt_t x);
+ pmt_t from_float(double x);
+ double to_float(pmt_t x);
bool is_complex(pmt_t obj);
pmt_t make_rectangular(double re, double im);
diff --git a/gr-analog/grc/analog_probe_avg_mag_sqrd_x.xml b/gr-analog/grc/analog_probe_avg_mag_sqrd_x.xml
index b05ac6d0d1..482982b21f 100644
--- a/gr-analog/grc/analog_probe_avg_mag_sqrd_x.xml
+++ b/gr-analog/grc/analog_probe_avg_mag_sqrd_x.xml
@@ -11,6 +11,7 @@
<make>analog.probe_avg_mag_sqrd_$(type)($threshold, $alpha)</make>
<callback>set_alpha($alpha)</callback>
<callback>set_threshold($threshold)</callback>
+ <callback>reset()</callback>
<param>
<name>Type</name>
<key>type</key>
diff --git a/gr-analog/include/gnuradio/analog/probe_avg_mag_sqrd_c.h b/gr-analog/include/gnuradio/analog/probe_avg_mag_sqrd_c.h
index 781d72f742..e6816f7fb6 100644
--- a/gr-analog/include/gnuradio/analog/probe_avg_mag_sqrd_c.h
+++ b/gr-analog/include/gnuradio/analog/probe_avg_mag_sqrd_c.h
@@ -60,6 +60,7 @@ namespace gr {
virtual void set_alpha(double alpha) = 0;
virtual void set_threshold(double decibels) = 0;
+ virtual void reset() = 0;
};
} /* namespace analog */
diff --git a/gr-analog/include/gnuradio/analog/probe_avg_mag_sqrd_cf.h b/gr-analog/include/gnuradio/analog/probe_avg_mag_sqrd_cf.h
index 03f465b2c5..9aeb8761be 100644
--- a/gr-analog/include/gnuradio/analog/probe_avg_mag_sqrd_cf.h
+++ b/gr-analog/include/gnuradio/analog/probe_avg_mag_sqrd_cf.h
@@ -62,6 +62,7 @@ namespace gr {
virtual void set_alpha(double alpha) = 0;
virtual void set_threshold(double decibels) = 0;
+ virtual void reset() = 0;
};
} /* namespace analog */
diff --git a/gr-analog/include/gnuradio/analog/probe_avg_mag_sqrd_f.h b/gr-analog/include/gnuradio/analog/probe_avg_mag_sqrd_f.h
index b9424dbd96..66095c3709 100644
--- a/gr-analog/include/gnuradio/analog/probe_avg_mag_sqrd_f.h
+++ b/gr-analog/include/gnuradio/analog/probe_avg_mag_sqrd_f.h
@@ -62,6 +62,7 @@ namespace gr {
virtual void set_alpha (double alpha) = 0;
virtual void set_threshold (double decibels) = 0;
+ virtual void reset() = 0;
};
} /* namespace analog */
diff --git a/gr-analog/lib/probe_avg_mag_sqrd_c_impl.cc b/gr-analog/lib/probe_avg_mag_sqrd_c_impl.cc
index 78e0c842ed..3d04c8bc6f 100644
--- a/gr-analog/lib/probe_avg_mag_sqrd_c_impl.cc
+++ b/gr-analog/lib/probe_avg_mag_sqrd_c_impl.cc
@@ -87,5 +87,11 @@ namespace gr {
d_iir.set_taps(alpha);
}
+ void
+ probe_avg_mag_sqrd_c_impl::reset()
+ {
+ d_iir.reset();
+ }
+
} /* namespace analog */
} /* namespace gr */
diff --git a/gr-analog/lib/probe_avg_mag_sqrd_c_impl.h b/gr-analog/lib/probe_avg_mag_sqrd_c_impl.h
index cddb9a7234..0128491f9d 100644
--- a/gr-analog/lib/probe_avg_mag_sqrd_c_impl.h
+++ b/gr-analog/lib/probe_avg_mag_sqrd_c_impl.h
@@ -48,6 +48,7 @@ namespace gr {
void set_alpha(double alpha);
void set_threshold(double decibels);
+ void reset();
int work(int noutput_items,
gr_vector_const_void_star &input_items,
diff --git a/gr-analog/lib/probe_avg_mag_sqrd_cf_impl.cc b/gr-analog/lib/probe_avg_mag_sqrd_cf_impl.cc
index 76d54880d4..c57f5cefd8 100644
--- a/gr-analog/lib/probe_avg_mag_sqrd_cf_impl.cc
+++ b/gr-analog/lib/probe_avg_mag_sqrd_cf_impl.cc
@@ -89,5 +89,11 @@ namespace gr {
d_iir.set_taps(alpha);
}
+ void
+ probe_avg_mag_sqrd_cf_impl::reset()
+ {
+ d_iir.reset();
+ }
+
} /* namespace analog */
} /* namespace gr */
diff --git a/gr-analog/lib/probe_avg_mag_sqrd_cf_impl.h b/gr-analog/lib/probe_avg_mag_sqrd_cf_impl.h
index 359f7f8d53..0284981cac 100644
--- a/gr-analog/lib/probe_avg_mag_sqrd_cf_impl.h
+++ b/gr-analog/lib/probe_avg_mag_sqrd_cf_impl.h
@@ -48,6 +48,7 @@ namespace gr {
void set_alpha(double alpha);
void set_threshold(double decibels);
+ void reset();
int work(int noutput_items,
gr_vector_const_void_star &input_items,
diff --git a/gr-analog/lib/probe_avg_mag_sqrd_f_impl.cc b/gr-analog/lib/probe_avg_mag_sqrd_f_impl.cc
index 505a24a5e9..0d2ce63f7b 100644
--- a/gr-analog/lib/probe_avg_mag_sqrd_f_impl.cc
+++ b/gr-analog/lib/probe_avg_mag_sqrd_f_impl.cc
@@ -87,6 +87,12 @@ namespace gr {
d_iir.set_taps(alpha);
}
+ void
+ probe_avg_mag_sqrd_f_impl::reset()
+ {
+ d_iir.reset();
+ }
+
} /* namespace analog */
} /* namespace gr */
diff --git a/gr-analog/lib/probe_avg_mag_sqrd_f_impl.h b/gr-analog/lib/probe_avg_mag_sqrd_f_impl.h
index bdccfc7b3a..1f82f85e18 100644
--- a/gr-analog/lib/probe_avg_mag_sqrd_f_impl.h
+++ b/gr-analog/lib/probe_avg_mag_sqrd_f_impl.h
@@ -48,6 +48,7 @@ namespace gr {
void set_alpha(double alpha);
void set_threshold(double decibels);
+ void reset();
int work(int noutput_items,
gr_vector_const_void_star &input_items,
diff --git a/gr-blocks/examples/CMakeLists.txt b/gr-blocks/examples/CMakeLists.txt
index c9829661b6..bb07cdc2b5 100644
--- a/gr-blocks/examples/CMakeLists.txt
+++ b/gr-blocks/examples/CMakeLists.txt
@@ -17,6 +17,14 @@
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
+install(
+ FILES
+ matrix_multiplexer.grc
+ vector_source_with_tags.grc
+ DESTINATION ${GR_PKG_DATA_DIR}/examples/blocks
+ COMPONENT "runtime_python"
+)
+
add_subdirectory(metadata)
add_subdirectory(tags)
diff --git a/gr-blocks/examples/msg_passing/strobe.grc b/gr-blocks/examples/msg_passing/strobe.grc
index e5001a4262..f24887ab76 100644
--- a/gr-blocks/examples/msg_passing/strobe.grc
+++ b/gr-blocks/examples/msg_passing/strobe.grc
@@ -1,4 +1,5 @@
<?xml version='1.0' encoding='ASCII'?>
+<?grc format='1' created='3.7.6'?>
<flow_graph>
<timestamp>Sun Mar 17 20:42:59 2013</timestamp>
<block>
@@ -52,8 +53,12 @@
<value></value>
</param>
<param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
<key>_coordinate</key>
- <value>(10, 10)</value>
+ <value>(-8, -12)</value>
</param>
<param>
<key>_rotation</key>
@@ -61,41 +66,42 @@
</param>
</block>
<block>
- <key>variable</key>
+ <key>blocks_pdu_to_tagged_stream</key>
<param>
<key>id</key>
- <value>samp_rate</value>
+ <value>blocks_pdu_to_tagged_stream_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>value</key>
- <value>32000</value>
+ <key>type</key>
+ <value>byte</value>
</param>
<param>
- <key>_coordinate</key>
- <value>(10, 170)</value>
+ <key>tag</key>
+ <value>packet_len</value>
</param>
<param>
- <key>_rotation</key>
- <value>0</value>
+ <key>alias</key>
+ <value></value>
</param>
- </block>
- <block>
- <key>blocks_message_debug</key>
<param>
- <key>id</key>
- <value>blocks_message_debug_0</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
- <key>_enabled</key>
- <value>True</value>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
</param>
<param>
<key>_coordinate</key>
- <value>(1049, 176)</value>
+ <value>(264, 179)</value>
</param>
<param>
<key>_rotation</key>
@@ -103,22 +109,42 @@
</param>
</block>
<block>
- <key>blocks_pdu_to_tagged_stream</key>
+ <key>blocks_message_strobe</key>
<param>
<key>id</key>
- <value>blocks_pdu_to_tagged_stream_0</value>
+ <value>blocks_message_strobe_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>byte</value>
+ <key>msg</key>
+ <value>pmt.cons( pmt.PMT_NIL, pmt.make_u8vector(512,0) )</value>
+ </param>
+ <param>
+ <key>period</key>
+ <value>750</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
</param>
<param>
<key>_coordinate</key>
- <value>(388, 85)</value>
+ <value>(48, 172)</value>
</param>
<param>
<key>_rotation</key>
@@ -129,7 +155,7 @@
<key>blocks_message_strobe</key>
<param>
<key>id</key>
- <value>blocks_message_strobe_0_0</value>
+ <value>blocks_message_strobe_0</value>
</param>
<param>
<key>_enabled</key>
@@ -137,15 +163,31 @@
</param>
<param>
<key>msg</key>
- <value>pmt.cons( pmt.PMT_NIL, pmt.make_u8vector(512,0) )</value>
+ <value>pmt.intern("TEST")</value>
</param>
<param>
<key>period</key>
- <value>750</value>
+ <value>1000</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
</param>
<param>
<key>_coordinate</key>
- <value>(95, 95)</value>
+ <value>(56, 108)</value>
</param>
<param>
<key>_rotation</key>
@@ -175,8 +217,28 @@
<value>1</value>
</param>
<param>
+ <key>showports</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
<key>_coordinate</key>
- <value>(629, 81)</value>
+ <value>(496, 179)</value>
</param>
<param>
<key>_rotation</key>
@@ -198,8 +260,28 @@
<value>byte</value>
</param>
<param>
+ <key>tag</key>
+ <value>packet_len</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
<key>_coordinate</key>
- <value>(837, 47)</value>
+ <value>(664, 179)</value>
</param>
<param>
<key>_rotation</key>
@@ -207,26 +289,26 @@
</param>
</block>
<block>
- <key>blocks_message_strobe</key>
+ <key>blocks_message_debug</key>
<param>
<key>id</key>
- <value>blocks_message_strobe_0</value>
+ <value>blocks_message_debug_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>msg</key>
- <value>pmt.intern("TEST")</value>
+ <key>alias</key>
+ <value></value>
</param>
<param>
- <key>period</key>
- <value>1000</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(423, 164)</value>
+ <value>(944, 120)</value>
</param>
<param>
<key>_rotation</key>
@@ -234,22 +316,16 @@
</param>
</block>
<connection>
- <source_block_id>blocks_message_strobe_0</source_block_id>
- <sink_block_id>blocks_message_debug_0</sink_block_id>
- <source_key>0</source_key>
- <sink_key>0</sink_key>
- </connection>
- <connection>
<source_block_id>blocks_message_strobe_0_0</source_block_id>
<sink_block_id>blocks_pdu_to_tagged_stream_0</sink_block_id>
- <source_key>0</source_key>
- <sink_key>0</sink_key>
+ <source_key>strobe</source_key>
+ <sink_key>pdus</sink_key>
</connection>
<connection>
- <source_block_id>blocks_tagged_stream_to_pdu_0</source_block_id>
- <sink_block_id>blocks_message_debug_0</sink_block_id>
+ <source_block_id>blocks_pdu_to_tagged_stream_0</source_block_id>
+ <sink_block_id>blocks_copy_0</sink_block_id>
<source_key>0</source_key>
- <sink_key>2</sink_key>
+ <sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_copy_0</source_block_id>
@@ -258,9 +334,15 @@
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_pdu_to_tagged_stream_0</source_block_id>
- <sink_block_id>blocks_copy_0</sink_block_id>
- <source_key>0</source_key>
- <sink_key>0</sink_key>
+ <source_block_id>blocks_message_strobe_0</source_block_id>
+ <sink_block_id>blocks_message_debug_0</sink_block_id>
+ <source_key>strobe</source_key>
+ <sink_key>print</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_tagged_stream_to_pdu_0</source_block_id>
+ <sink_block_id>blocks_message_debug_0</sink_block_id>
+ <source_key>pdus</source_key>
+ <sink_key>print_pdu</sink_key>
</connection>
</flow_graph>
diff --git a/gr-blocks/examples/vector_source_with_tags.grc b/gr-blocks/examples/vector_source_with_tags.grc
new file mode 100644
index 0000000000..e266b91f85
--- /dev/null
+++ b/gr-blocks/examples/vector_source_with_tags.grc
@@ -0,0 +1,698 @@
+<?xml version='1.0' encoding='ASCII'?>
+<?grc format='1' created='3.7.6'?>
+<flow_graph>
+ <timestamp>Mon Sep 22 11:59:58 2014</timestamp>
+ <block>
+ <key>options</key>
+ <param>
+ <key>id</key>
+ <value>vector_source_with_tags</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>Shows how to use tags in a vector_source</value>
+ </param>
+ <param>
+ <key>window_size</key>
+ <value>1280, 1024</value>
+ </param>
+ <param>
+ <key>generate_options</key>
+ <value>qt_gui</value>
+ </param>
+ <param>
+ <key>category</key>
+ <value>Custom</value>
+ </param>
+ <param>
+ <key>run_options</key>
+ <value>prompt</value>
+ </param>
+ <param>
+ <key>run</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>max_nouts</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>realtime_scheduling</key>
+ <value></value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(10, 10)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>tag1</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>gr.tag_utils.python_to_tag((1, pmt.intern('mark'), pmt.PMT_T))</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(16, 267)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>tag0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>gr.tag_utils.python_to_tag((0, pmt.intern('mark'), pmt.PMT_T, pmt.intern("src")))</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(16, 203)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>32000</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(184, 11)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>import</key>
+ <param>
+ <key>id</key>
+ <value>import_pmt</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>import</key>
+ <value>import pmt</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(280, 11)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_throttle</key>
+ <param>
+ <key>id</key>
+ <value>blocks_throttle_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>samples_per_second</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>ignoretag</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(272, 123)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_tag_debug</key>
+ <param>
+ <key>id</key>
+ <value>blocks_tag_debug_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>name</key>
+ <value></value>
+ </param>
+ <param>
+ <key>filter</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>num_inputs</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>display</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(456, 195)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_vector_source_x</key>
+ <param>
+ <key>id</key>
+ <value>blocks_vector_source_x_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>vector</key>
+ <value>(-0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 0.0)</value>
+ </param>
+ <param>
+ <key>tags</key>
+ <value>[tag0, tag1]</value>
+ </param>
+ <param>
+ <key>repeat</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(16, 107)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>qtgui_time_sink_x</key>
+ <param>
+ <key>id</key>
+ <value>qtgui_time_sink_x_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>name</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>ylabel</key>
+ <value>Amplitude</value>
+ </param>
+ <param>
+ <key>yunit</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>size</key>
+ <value>60</value>
+ </param>
+ <param>
+ <key>srate</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>grid</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>autoscale</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ymin</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>ymax</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>nconnections</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>update_time</key>
+ <value>0.10</value>
+ </param>
+ <param>
+ <key>entags</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value></value>
+ </param>
+ <param>
+ <key>tr_mode</key>
+ <value>qtgui.TRIG_MODE_TAG</value>
+ </param>
+ <param>
+ <key>tr_slope</key>
+ <value>qtgui.TRIG_SLOPE_POS</value>
+ </param>
+ <param>
+ <key>tr_level</key>
+ <value>0.0</value>
+ </param>
+ <param>
+ <key>tr_delay</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>tr_chan</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>tr_tag</key>
+ <value>mark</value>
+ </param>
+ <param>
+ <key>label1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width1</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color1</key>
+ <value>"blue"</value>
+ </param>
+ <param>
+ <key>style1</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>marker1</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alpha1</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width2</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color2</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>style2</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>marker2</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>alpha2</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width3</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color3</key>
+ <value>"green"</value>
+ </param>
+ <param>
+ <key>style3</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>marker3</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>alpha3</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width4</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color4</key>
+ <value>"black"</value>
+ </param>
+ <param>
+ <key>style4</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>marker4</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>alpha4</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width5</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color5</key>
+ <value>"cyan"</value>
+ </param>
+ <param>
+ <key>style5</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>marker5</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>alpha5</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width6</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color6</key>
+ <value>"magenta"</value>
+ </param>
+ <param>
+ <key>style6</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>marker6</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>alpha6</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width7</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color7</key>
+ <value>"yellow"</value>
+ </param>
+ <param>
+ <key>style7</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>marker7</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>alpha7</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label8</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width8</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color8</key>
+ <value>"dark red"</value>
+ </param>
+ <param>
+ <key>style8</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>marker8</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>alpha8</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label9</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width9</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color9</key>
+ <value>"dark green"</value>
+ </param>
+ <param>
+ <key>style9</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>marker9</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>alpha9</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label10</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width10</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color10</key>
+ <value>"blue"</value>
+ </param>
+ <param>
+ <key>style10</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>marker10</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>alpha10</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(456, 107)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <connection>
+ <source_block_id>blocks_throttle_0</source_block_id>
+ <sink_block_id>qtgui_time_sink_x_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_vector_source_x_0</source_block_id>
+ <sink_block_id>blocks_throttle_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_throttle_0</source_block_id>
+ <sink_block_id>blocks_tag_debug_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+</flow_graph>
diff --git a/gr-blocks/grc/blocks_abs_xx.xml b/gr-blocks/grc/blocks_abs_xx.xml
index 65ef97ddff..77298716c8 100644
--- a/gr-blocks/grc/blocks_abs_xx.xml
+++ b/gr-blocks/grc/blocks_abs_xx.xml
@@ -8,7 +8,13 @@
<name>Abs</name>
<key>blocks_abs_xx</key>
<import>from gnuradio import blocks</import>
- <make>blocks.abs_$(type.fcn)()</make>
+ <make>blocks.abs_$(type.fcn)($vlen)</make>
+ <param>
+ <name>Vec Length</name>
+ <key>vlen</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
<param>
<name>IO Type</name>
<key>type</key>
@@ -29,21 +35,14 @@
<opt>fcn:ff</opt>
</option>
</param>
- <param>
- <name>Num Inputs</name>
- <key>num_inputs</key>
- <value>1</value>
- <type>int</type>
- </param>
- <check>$num_inputs &gt;= 1</check>
<sink>
<name>in</name>
<type>$type</type>
- <nports>$num_inputs</nports>
+ <vlen>$vlen</vlen>
</sink>
<source>
<name>out</name>
<type>$type</type>
- <nports>$num_inputs</nports>
+ <vlen>$vlen</vlen>
</source>
</block>
diff --git a/gr-blocks/grc/blocks_tagged_stream_to_pdu.xml b/gr-blocks/grc/blocks_tagged_stream_to_pdu.xml
index f85b47fb19..ae8ad3b6c5 100644
--- a/gr-blocks/grc/blocks_tagged_stream_to_pdu.xml
+++ b/gr-blocks/grc/blocks_tagged_stream_to_pdu.xml
@@ -42,5 +42,6 @@
<source>
<name>pdus</name>
<type>message</type>
+ <optional>1</optional>
</source>
</block>
diff --git a/gr-blocks/include/gnuradio/blocks/abs_XX.h.t b/gr-blocks/include/gnuradio/blocks/abs_XX.h.t
index f8688edcd3..541716296f 100644
--- a/gr-blocks/include/gnuradio/blocks/abs_XX.h.t
+++ b/gr-blocks/include/gnuradio/blocks/abs_XX.h.t
@@ -49,7 +49,7 @@ namespace gr {
/*!
* \brief Create an instance of @NAME@
*/
- static sptr make();
+ static sptr make(size_t vlen=1);
};
} /* namespace blocks */
diff --git a/gr-blocks/include/gnuradio/blocks/control_loop.h b/gr-blocks/include/gnuradio/blocks/control_loop.h
index f7ff9770f9..821c3824ec 100644
--- a/gr-blocks/include/gnuradio/blocks/control_loop.h
+++ b/gr-blocks/include/gnuradio/blocks/control_loop.h
@@ -268,6 +268,87 @@ namespace gr {
float get_min_freq() const;
};
+ // This is a table of tanh(x) for x in [-2, 2] used in tanh_lut.
+ static float
+ tanh_lut_table[256] = { -0.96402758, -0.96290241, -0.96174273, -0.96054753, -0.95931576,
+ -0.95804636, -0.95673822, -0.95539023, -0.95400122, -0.95257001,
+ -0.95109539, -0.9495761 , -0.94801087, -0.94639839, -0.94473732,
+ -0.94302627, -0.94126385, -0.93944862, -0.93757908, -0.93565374,
+ -0.93367104, -0.93162941, -0.92952723, -0.92736284, -0.92513456,
+ -0.92284066, -0.92047938, -0.91804891, -0.91554743, -0.91297305,
+ -0.91032388, -0.90759795, -0.9047933 , -0.90190789, -0.89893968,
+ -0.89588656, -0.89274642, -0.88951709, -0.88619637, -0.88278203,
+ -0.87927182, -0.87566342, -0.87195453, -0.86814278, -0.86422579,
+ -0.86020115, -0.85606642, -0.85181914, -0.84745683, -0.84297699,
+ -0.83837709, -0.83365461, -0.82880699, -0.82383167, -0.81872609,
+ -0.81348767, -0.80811385, -0.80260204, -0.7969497 , -0.79115425,
+ -0.78521317, -0.77912392, -0.772884 , -0.76649093, -0.75994227,
+ -0.75323562, -0.74636859, -0.73933889, -0.73214422, -0.7247824 ,
+ -0.71725127, -0.70954876, -0.70167287, -0.6936217 , -0.68539341,
+ -0.67698629, -0.66839871, -0.65962916, -0.65067625, -0.64153871,
+ -0.6322154 , -0.62270534, -0.61300768, -0.60312171, -0.59304692,
+ -0.58278295, -0.57232959, -0.56168685, -0.55085493, -0.53983419,
+ -0.52862523, -0.51722883, -0.50564601, -0.49387799, -0.48192623,
+ -0.46979241, -0.45747844, -0.44498647, -0.4323189 , -0.41947836,
+ -0.40646773, -0.39329014, -0.37994896, -0.36644782, -0.35279057,
+ -0.33898135, -0.32502449, -0.31092459, -0.2966865 , -0.28231527,
+ -0.26781621, -0.25319481, -0.23845682, -0.22360817, -0.208655 ,
+ -0.19360362, -0.17846056, -0.16323249, -0.14792623, -0.13254879,
+ -0.11710727, -0.10160892, -0.08606109, -0.07047123, -0.05484686,
+ -0.0391956 , -0.02352507, -0.00784298, 0.00784298, 0.02352507,
+ 0.0391956 , 0.05484686, 0.07047123, 0.08606109, 0.10160892,
+ 0.11710727, 0.13254879, 0.14792623, 0.16323249, 0.17846056,
+ 0.19360362, 0.208655 , 0.22360817, 0.23845682, 0.25319481,
+ 0.26781621, 0.28231527, 0.2966865 , 0.31092459, 0.32502449,
+ 0.33898135, 0.35279057, 0.36644782, 0.37994896, 0.39329014,
+ 0.40646773, 0.41947836, 0.4323189 , 0.44498647, 0.45747844,
+ 0.46979241, 0.48192623, 0.49387799, 0.50564601, 0.51722883,
+ 0.52862523, 0.53983419, 0.55085493, 0.56168685, 0.57232959,
+ 0.58278295, 0.59304692, 0.60312171, 0.61300768, 0.62270534,
+ 0.6322154 , 0.64153871, 0.65067625, 0.65962916, 0.66839871,
+ 0.67698629, 0.68539341, 0.6936217 , 0.70167287, 0.70954876,
+ 0.71725127, 0.7247824 , 0.73214422, 0.73933889, 0.74636859,
+ 0.75323562, 0.75994227, 0.76649093, 0.772884 , 0.77912392,
+ 0.78521317, 0.79115425, 0.7969497 , 0.80260204, 0.80811385,
+ 0.81348767, 0.81872609, 0.82383167, 0.82880699, 0.83365461,
+ 0.83837709, 0.84297699, 0.84745683, 0.85181914, 0.85606642,
+ 0.86020115, 0.86422579, 0.86814278, 0.87195453, 0.87566342,
+ 0.87927182, 0.88278203, 0.88619637, 0.88951709, 0.89274642,
+ 0.89588656, 0.89893968, 0.90190789, 0.9047933 , 0.90759795,
+ 0.91032388, 0.91297305, 0.91554743, 0.91804891, 0.92047938,
+ 0.92284066, 0.92513456, 0.92736284, 0.92952723, 0.93162941,
+ 0.93367104, 0.93565374, 0.93757908, 0.93944862, 0.94126385,
+ 0.94302627, 0.94473732, 0.94639839, 0.94801087, 0.9495761 ,
+ 0.95109539, 0.95257001, 0.95400122, 0.95539023, 0.95673822,
+ 0.95804636, 0.95931576, 0.96054753, 0.96174273, 0.96290241,
+ 0.96402758 };
+
+ /*!
+ * A look-up table (LUT) tanh calcuation. This function returns an
+ * estimate to tanh(x) based on a 256-point LUT between -2 and
+ * 2. If x < -2, it returns -1; if > 2, it retursn 1.
+ *
+ * This LUT form of the tanh is "hidden" in this code because it
+ * is likely too coarse an estimate for any real uses of a
+ * tanh. It is useful, however, in certain control loop
+ * applications where the input is expected to be within these
+ * bounds and the noise will be greater than the quanitzation of
+ * this small LUT. For more accurate forms of tanh, see
+ * volk_32f_tanh_32f.
+ */
+ static inline float
+ tanhf_lut(float x)
+ {
+ if(x > 2)
+ return 1;
+ else if(x <= -2)
+ return -1;
+ else {
+ int index = 128 + 64*x;
+ return tanh_lut_table[index];
+ }
+ }
+
} /* namespace blocks */
} /* namespace gr */
diff --git a/gr-blocks/include/gnuradio/blocks/pdu_to_tagged_stream.h b/gr-blocks/include/gnuradio/blocks/pdu_to_tagged_stream.h
index 9ae2ecd297..479e367e72 100644
--- a/gr-blocks/include/gnuradio/blocks/pdu_to_tagged_stream.h
+++ b/gr-blocks/include/gnuradio/blocks/pdu_to_tagged_stream.h
@@ -25,7 +25,7 @@
#include <gnuradio/blocks/api.h>
#include <gnuradio/blocks/pdu.h>
-#include <gnuradio/sync_block.h>
+#include <gnuradio/tagged_stream_block.h>
namespace gr {
namespace blocks {
@@ -34,7 +34,7 @@ namespace gr {
* \brief Turns received PDUs into a tagged stream of items
* \ingroup message_tools_blk
*/
- class BLOCKS_API pdu_to_tagged_stream : virtual public sync_block
+ class BLOCKS_API pdu_to_tagged_stream : virtual public tagged_stream_block
{
public:
// gr::blocks::pdu_to_tagged_stream::sptr
diff --git a/gr-blocks/lib/abs_XX_impl.cc.t b/gr-blocks/lib/abs_XX_impl.cc.t
index 6bb9f149fd..195d8dff3d 100644
--- a/gr-blocks/lib/abs_XX_impl.cc.t
+++ b/gr-blocks/lib/abs_XX_impl.cc.t
@@ -32,15 +32,16 @@
namespace gr {
namespace blocks {
- @NAME@::sptr @NAME@::make()
+ @NAME@::sptr @NAME@::make(size_t vlen)
{
- return gnuradio::get_initial_sptr(new @NAME_IMPL@());
+ return gnuradio::get_initial_sptr(new @NAME_IMPL@(vlen));
}
- @NAME_IMPL@::@NAME_IMPL@()
+ @NAME_IMPL@::@NAME_IMPL@(size_t vlen)
: sync_block ("@NAME@",
- io_signature::make (1, 1, sizeof (@I_TYPE@)),
- io_signature::make (1, 1, sizeof (@O_TYPE@)))
+ io_signature::make (1, 1, sizeof (@I_TYPE@)*vlen),
+ io_signature::make (1, 1, sizeof (@O_TYPE@)*vlen)),
+ d_vlen(vlen)
{
}
@@ -52,7 +53,7 @@ namespace gr {
@I_TYPE@ *iptr = (@I_TYPE@ *) input_items[0];
@O_TYPE@ *optr = (@O_TYPE@ *) output_items[0];
- for(int i=0; i<noutput_items; i++) {
+ for(size_t i=0; i<noutput_items*d_vlen; i++) {
@I_TYPE@ val = iptr[i];
optr[i] = ((val < ((@I_TYPE@)0)) ? -val : val);
}
diff --git a/gr-blocks/lib/abs_XX_impl.h.t b/gr-blocks/lib/abs_XX_impl.h.t
index b31ef5fb31..fa96c84073 100644
--- a/gr-blocks/lib/abs_XX_impl.h.t
+++ b/gr-blocks/lib/abs_XX_impl.h.t
@@ -32,8 +32,11 @@ namespace gr {
class BLOCKS_API @NAME_IMPL@ : public @NAME@
{
+ private:
+ size_t d_vlen;
+
public:
- @NAME_IMPL@();
+ @NAME_IMPL@(size_t vlen);
int work(int noutput_items,
gr_vector_const_void_star &input_items,
diff --git a/gr-blocks/lib/deinterleave_impl.cc b/gr-blocks/lib/deinterleave_impl.cc
index c9d0e9aeda..9e18c35e58 100644
--- a/gr-blocks/lib/deinterleave_impl.cc
+++ b/gr-blocks/lib/deinterleave_impl.cc
@@ -41,13 +41,20 @@ namespace gr {
io_signature::make (1, io_signature::IO_INFINITE, itemsize)),
d_itemsize(itemsize), d_blocksize(blocksize), d_current_output(0)
{
+ d_size_bytes = d_itemsize * d_blocksize;
set_output_multiple(blocksize);
}
+ void
+ deinterleave_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required)
+ {
+ ninput_items_required[0] = noutput_items * d_noutputs;
+ }
+
bool
deinterleave_impl::check_topology(int ninputs, int noutputs)
{
- set_relative_rate((double)noutputs);
+ set_relative_rate(1.0/(double)noutputs);
d_noutputs = noutputs;
return true;
}
@@ -61,10 +68,29 @@ namespace gr {
const char *in = (const char*)input_items[0];
char **out = (char**)&output_items[0];
- memcpy(out[d_current_output], in, d_itemsize * d_blocksize);
- consume_each(d_blocksize);
- produce(d_current_output, d_blocksize);
- d_current_output = (d_current_output + 1) % d_noutputs;
+ int count = 0, totalcount = noutput_items*d_noutputs;
+ unsigned int skip = 0;
+ unsigned int acc = 0;
+ while(count < totalcount) {
+ memcpy(out[d_current_output]+skip*d_size_bytes, in, d_size_bytes);
+ in += d_size_bytes;
+ produce(d_current_output, d_blocksize);
+ d_current_output = (d_current_output + 1) % d_noutputs;
+
+ // accumulate times through the loop; increment skip after a
+ // full pass over the output streams.
+ // This is separate than d_current_output since we could be in
+ // the middle of a loop when we exit.
+ acc++;
+ if(acc >= d_noutputs) {
+ skip++;
+ acc = 0;
+ }
+
+ // Keep track of our loop counter
+ count+=d_blocksize;
+ }
+ consume_each(totalcount);
return WORK_CALLED_PRODUCE;
}
diff --git a/gr-blocks/lib/deinterleave_impl.h b/gr-blocks/lib/deinterleave_impl.h
index 247ee3a018..71a551a69c 100644
--- a/gr-blocks/lib/deinterleave_impl.h
+++ b/gr-blocks/lib/deinterleave_impl.h
@@ -35,11 +35,12 @@ namespace gr {
unsigned int d_blocksize;
unsigned int d_current_output;
unsigned int d_noutputs;
-
+ unsigned int d_size_bytes; // block size in bytes
public:
deinterleave_impl(size_t itemsize, unsigned int blocksize);
+ void forecast(int noutput_items, gr_vector_int &ninput_items_required);
bool check_topology(int ninputs, int noutputs);
int general_work(int noutput_items,
diff --git a/gr-blocks/lib/message_strobe_impl.cc b/gr-blocks/lib/message_strobe_impl.cc
index bd0ad80142..b3f1782229 100644
--- a/gr-blocks/lib/message_strobe_impl.cc
+++ b/gr-blocks/lib/message_strobe_impl.cc
@@ -47,15 +47,15 @@ namespace gr {
message_strobe_impl::message_strobe_impl(pmt::pmt_t msg, float period_ms)
: block("message_strobe",
- io_signature::make(0, 0, 0),
- io_signature::make(0, 0, 0)),
+ io_signature::make(0, 0, 0),
+ io_signature::make(0, 0, 0)),
d_finished(false),
d_period_ms(period_ms),
d_msg(msg)
{
message_port_register_out(pmt::mp("strobe"));
- d_thread = boost::shared_ptr<boost::thread>
- (new boost::thread(boost::bind(&message_strobe_impl::run, this)));
+ d_thread = boost::shared_ptr<gr::thread::thread>
+ (new gr::thread::thread(boost::bind(&message_strobe_impl::run, this)));
message_port_register_in(pmt::mp("set_msg"));
set_msg_handler(pmt::mp("set_msg"),
diff --git a/gr-blocks/lib/message_strobe_impl.h b/gr-blocks/lib/message_strobe_impl.h
index 7a54680286..0f37cd2e0e 100644
--- a/gr-blocks/lib/message_strobe_impl.h
+++ b/gr-blocks/lib/message_strobe_impl.h
@@ -31,7 +31,7 @@ namespace gr {
class BLOCKS_API message_strobe_impl : public message_strobe
{
private:
- boost::shared_ptr<boost::thread> d_thread;
+ boost::shared_ptr<gr::thread::thread> d_thread;
bool d_finished;
float d_period_ms;
pmt::pmt_t d_msg;
diff --git a/gr-blocks/lib/message_strobe_random_impl.cc b/gr-blocks/lib/message_strobe_random_impl.cc
index 80819fc2fc..c62aad1c7a 100644
--- a/gr-blocks/lib/message_strobe_random_impl.cc
+++ b/gr-blocks/lib/message_strobe_random_impl.cc
@@ -61,8 +61,8 @@ namespace gr {
// set up ports
message_port_register_out(pmt::mp("strobe"));
- d_thread = boost::shared_ptr<boost::thread>
- (new boost::thread(boost::bind(&message_strobe_random_impl::run, this)));
+ d_thread = boost::shared_ptr<gr::thread::thread>
+ (new gr::thread::thread(boost::bind(&message_strobe_random_impl::run, this)));
message_port_register_in(pmt::mp("set_msg"));
set_msg_handler(pmt::mp("set_msg"),
diff --git a/gr-blocks/lib/message_strobe_random_impl.h b/gr-blocks/lib/message_strobe_random_impl.h
index 32eddb592c..2dcaa7effa 100644
--- a/gr-blocks/lib/message_strobe_random_impl.h
+++ b/gr-blocks/lib/message_strobe_random_impl.h
@@ -36,7 +36,7 @@ namespace gr {
class BLOCKS_API message_strobe_random_impl : public message_strobe_random
{
private:
- boost::shared_ptr<boost::thread> d_thread;
+ boost::shared_ptr<gr::thread::thread> d_thread;
bool d_finished;
float d_mean_ms;
float d_std_ms;
diff --git a/gr-blocks/lib/pdu_to_tagged_stream_impl.cc b/gr-blocks/lib/pdu_to_tagged_stream_impl.cc
index 8baa9773d6..a8ba5d22b9 100644
--- a/gr-blocks/lib/pdu_to_tagged_stream_impl.cc
+++ b/gr-blocks/lib/pdu_to_tagged_stream_impl.cc
@@ -32,90 +32,79 @@ namespace gr {
namespace blocks {
pdu_to_tagged_stream::sptr
- pdu_to_tagged_stream::make(pdu::vector_type type, const std::string& lengthtagname)
+ pdu_to_tagged_stream::make(pdu::vector_type type, const std::string& tsb_tag_key)
{
- return gnuradio::get_initial_sptr(new pdu_to_tagged_stream_impl(type, lengthtagname));
+ return gnuradio::get_initial_sptr(new pdu_to_tagged_stream_impl(type, tsb_tag_key));
}
- pdu_to_tagged_stream_impl::pdu_to_tagged_stream_impl(pdu::vector_type type, const std::string& lengthtagname)
- : sync_block("pdu_to_tagged_stream",
- io_signature::make(0, 0, 0),
- io_signature::make(1, 1, pdu::itemsize(type))),
- d_itemsize(pdu::itemsize(type)),
- d_type(type),
- d_tag(pmt::mp(lengthtagname))
+ pdu_to_tagged_stream_impl::pdu_to_tagged_stream_impl(pdu::vector_type type, const std::string& tsb_tag_key)
+ : tagged_stream_block("pdu_to_tagged_stream",
+ io_signature::make(0, 0, 0),
+ io_signature::make(1, 1, pdu::itemsize(type)),
+ tsb_tag_key),
+ d_itemsize(pdu::itemsize(type)),
+ d_type(type),
+ d_curr_len(0)
{
message_port_register_in(PDU_PORT_ID);
}
- int
- pdu_to_tagged_stream_impl::work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
+ int pdu_to_tagged_stream_impl::calculate_output_stream_length(const gr_vector_int &)
{
- char *out = (char *)output_items[0];
- int nout = 0;
-
- // if we have remaining output, send it
- if (d_remain.size() > 0) {
- nout = std::min((size_t)d_remain.size()/d_itemsize, (size_t)noutput_items);
- memcpy(out, &d_remain[0], nout*d_itemsize);
- d_remain.erase(d_remain.begin(), d_remain.begin()+nout*d_itemsize);
- noutput_items -= nout;
- out += nout*d_itemsize;
- }
-
- // if we have space for at least one item output as much as we can
- if (noutput_items > 0) {
-
- // grab a message if one exists
- pmt::pmt_t msg(delete_head_nowait(PDU_PORT_ID));
- if (msg.get() == NULL)
- return nout;
-
- // make sure type is valid
- if (!pmt::is_pair(msg)) // TODO: implement pdu::is_valid()
- throw std::runtime_error("received a malformed pdu message");
-
- // grab the components of the pdu message
- pmt::pmt_t meta(pmt::car(msg));
- pmt::pmt_t vect(pmt::cdr(msg));
+ if (d_curr_len == 0) {
+ pmt::pmt_t msg(delete_head_nowait(PDU_PORT_ID));
+ if (msg.get() == NULL) {
+ return 0;
+ }
- // compute offset for output tag
- uint64_t offset = nitems_written(0) + nout;
+ if (!pmt::is_pair(msg))
+ throw std::runtime_error("received a malformed pdu message");
- // add a tag for pdu length
- add_item_tag(0, offset, d_tag, pmt::from_long(pmt::length(vect)), pmt::mp(alias()));
+ d_curr_meta = pmt::car(msg);
+ d_curr_vect = pmt::cdr(msg);
+ d_curr_len = pmt::length(d_curr_vect);
+ }
- // if we recieved metadata add it as tags
- if (!pmt::eq(meta, pmt::PMT_NIL) ) {
- pmt::pmt_t klist(pmt::dict_keys(meta));
- for(size_t i=0; i<pmt::length(klist); i++){
- pmt::pmt_t k(pmt::nth(i, klist));
- pmt::pmt_t v(pmt::dict_ref(meta, k, pmt::PMT_NIL));
- add_item_tag(0, offset, k, v, pmt::mp(alias()));
- }
+ return d_curr_len;
}
- // copy vector output
- size_t ncopy = std::min((size_t)noutput_items, (size_t)pmt::length(vect));
- size_t nsave = pmt::length(vect) - ncopy;
+ int
+ pdu_to_tagged_stream_impl::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];
- // copy output
- size_t io(0);
- nout += ncopy;
- const uint8_t* ptr = (uint8_t*) uniform_vector_elements(vect, io);
- memcpy(out, ptr, ncopy*d_itemsize);
+ if (d_curr_len == 0) {
+ return 0;
+ }
- // save leftover items if needed for next work call
- if (nsave > 0) {
- d_remain.resize(nsave*d_itemsize, 0);
- memcpy(&d_remain[0], ptr + ncopy*d_itemsize, nsave*d_itemsize);
+ // work() should only be called if the current PDU fits entirely
+ // into the output buffer.
+ assert(noutput_items >= d_curr_len);
+
+ // Copy vector output
+ size_t nout = d_curr_len;
+ size_t io(0);
+ const uint8_t* ptr = (uint8_t*) uniform_vector_elements(d_curr_vect, io);
+ memcpy(out, ptr, d_curr_len*d_itemsize);
+
+ // Copy tags
+ if (!pmt::eq(d_curr_meta, pmt::PMT_NIL) ) {
+ pmt::pmt_t klist(pmt::dict_keys(d_curr_meta));
+ for (size_t i = 0; i < pmt::length(klist); i++) {
+ pmt::pmt_t k(pmt::nth(i, klist));
+ pmt::pmt_t v(pmt::dict_ref(d_curr_meta, k, pmt::PMT_NIL));
+ add_item_tag(0, nitems_written(0), k, v, pmt::mp(alias()));
}
}
+ // Reset state
+ d_curr_len = 0;
+
return nout;
- }
+ } /* work() */
} /* namespace blocks */
} /* namespace gr */
diff --git a/gr-blocks/lib/pdu_to_tagged_stream_impl.h b/gr-blocks/lib/pdu_to_tagged_stream_impl.h
index 4bfd9cfd4e..99f68147c8 100644
--- a/gr-blocks/lib/pdu_to_tagged_stream_impl.h
+++ b/gr-blocks/lib/pdu_to_tagged_stream_impl.h
@@ -32,18 +32,23 @@ namespace gr {
{
size_t d_itemsize;
pdu::vector_type d_type;
- std::vector<uint8_t> d_remain;
- pmt::pmt_t d_tag;
+ pmt::pmt_t d_curr_meta;
+ pmt::pmt_t d_curr_vect;
+ size_t d_curr_len;
public:
pdu_to_tagged_stream_impl(pdu::vector_type type, const std::string& lengthtagname="packet_len");
+ int calculate_output_stream_length(const gr_vector_int &ninput_items);
+
int work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items
+ );
};
} /* namespace blocks */
} /* namespace gr */
-#endif
+#endif /* INCLUDED_PDU_TO_TAGGED_STREAM_IMPL_H */
diff --git a/gr-blocks/lib/qa_block_tags.cc b/gr-blocks/lib/qa_block_tags.cc
index c554425f8e..d794f8edfe 100644
--- a/gr-blocks/lib/qa_block_tags.cc
+++ b/gr-blocks/lib/qa_block_tags.cc
@@ -33,20 +33,32 @@
#include <gnuradio/blocks/annotator_alltoall.h>
#include <gnuradio/blocks/annotator_1to1.h>
#include <gnuradio/blocks/keep_one_in_n.h>
-#include <gnuradio/tags.h>
// ----------------------------------------------------------------
// set to 1 to turn on debug output
// The debug output fully checks that the tags seen are what are expected. While
-// this behavior currently works with our implementation, there is no guarentee
+// this behavior currently works with our implementation, there is no guarantee
// that the tags will be coming in this specific order, so it's dangerous to
// rely on this as a test of the tag system working. We would really want to
// tags we know we should see and then test that they all occur once, but in no
// particular order.
#define QA_TAGS_DEBUG 0
+gr::tag_t make_tag(uint64_t offset, pmt::pmt_t key, pmt::pmt_t value, pmt::pmt_t srcid) {
+ gr::tag_t result;
+ result.offset = offset;
+ result.key = key;
+ result.value = value;
+ result.srcid = srcid;
+ return result;
+}
+
+std::ostream&
+operator << (std::ostream& os, const gr::tag_t &t) {
+ return os;
+}
void
qa_block_tags::t0()
{
@@ -59,8 +71,6 @@ qa_block_tags::t0()
tb->connect(src, 0, head, 0);
tb->connect(head, 0, snk, 0);
- //CPPUNIT_ASSERT_THROW(src->nitems_read(0), std::runtime_error);
- //CPPUNIT_ASSERT_THROW(src->nitems_written(0), std::runtime_error);
CPPUNIT_ASSERT_EQUAL(src->nitems_read(0), (uint64_t)0);
CPPUNIT_ASSERT_EQUAL(src->nitems_written(0), (uint64_t)0);
@@ -117,39 +127,39 @@ qa_block_tags::t1()
str1 << ann1->name() << ann1->unique_id();
str2 << ann2->name() << ann2->unique_id();
- pmt::pmt_t expected_tags3[8];
- expected_tags3[0] = mp(pmt::from_uint64(0), mp(str1.str()), mp("seq"), mp(0));
- expected_tags3[1] = mp(pmt::from_uint64(0), mp(str0.str()), mp("seq"), mp(0));
- expected_tags3[2] = mp(pmt::from_uint64(10000), mp(str1.str()), mp("seq"), mp(1));
- expected_tags3[3] = mp(pmt::from_uint64(10000), mp(str0.str()), mp("seq"), mp(2));
- expected_tags3[4] = mp(pmt::from_uint64(20000), mp(str1.str()), mp("seq"), mp(2));
- expected_tags3[5] = mp(pmt::from_uint64(20000), mp(str0.str()), mp("seq"), mp(4));
- expected_tags3[6] = mp(pmt::from_uint64(30000), mp(str1.str()), mp("seq"), mp(3));
- expected_tags3[7] = mp(pmt::from_uint64(30000), mp(str0.str()), mp("seq"), mp(6));
-
- pmt::pmt_t expected_tags4[8];
- expected_tags4[0] = mp(pmt::from_uint64(0), mp(str2.str()), mp("seq"), mp(0));
- expected_tags4[1] = mp(pmt::from_uint64(0), mp(str0.str()), mp("seq"), mp(1));
- expected_tags4[2] = mp(pmt::from_uint64(10000), mp(str2.str()), mp("seq"), mp(1));
- expected_tags4[3] = mp(pmt::from_uint64(10000), mp(str0.str()), mp("seq"), mp(3));
- expected_tags4[4] = mp(pmt::from_uint64(20000), mp(str2.str()), mp("seq"), mp(2));
- expected_tags4[5] = mp(pmt::from_uint64(20000), mp(str0.str()), mp("seq"), mp(5));
- expected_tags4[6] = mp(pmt::from_uint64(30000), mp(str2.str()), mp("seq"), mp(3));
- expected_tags4[7] = mp(pmt::from_uint64(30000), mp(str0.str()), mp("seq"), mp(7));
+ gr::tag_t expected_tags3[8];
+ expected_tags3[0] = make_tag(0, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags3[1] = make_tag(0, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags3[2] = make_tag(10000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(1));
+ expected_tags3[3] = make_tag(10000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags3[4] = make_tag(20000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags3[5] = make_tag(20000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(4));
+ expected_tags3[6] = make_tag(30000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(3));
+ expected_tags3[7] = make_tag(30000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(6));
+
+ gr::tag_t expected_tags4[8];
+ expected_tags4[0] = make_tag(0, pmt::mp(str2.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags4[1] = make_tag(0, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(1));
+ expected_tags4[2] = make_tag(10000, pmt::mp(str2.str()), pmt::mp("seq"), pmt::mp(1));
+ expected_tags4[3] = make_tag(10000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(3));
+ expected_tags4[4] = make_tag(20000, pmt::mp(str2.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags4[5] = make_tag(20000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(5));
+ expected_tags4[6] = make_tag(30000, pmt::mp(str2.str()), pmt::mp("seq"), pmt::mp(3));
+ expected_tags4[7] = make_tag(30000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(7));
std::cout << std::endl << "qa_block_tags::t1" << std::endl;
// For annotator 3, we know it gets tags from ann0 and ann1, test this
for(size_t i = 0; i < tags3.size(); i++) {
std::cout << "tags3[" << i << "] = " << tags3[i] << "\t\t" << expected_tags3[i] << std::endl;
- CPPUNIT_ASSERT_EQUAL(pmt::write_string(tags3[i]), pmt::write_string(expected_tags3[i]));
+ CPPUNIT_ASSERT_EQUAL(tags3[i], expected_tags3[i]);
}
// For annotator 4, we know it gets tags from ann0 and ann2, test this
std::cout << std::endl;
for(size_t i = 0; i < tags4.size(); i++) {
std::cout << "tags4[" << i << "] = " << tags4[i] << "\t\t" << expected_tags4[i] << std::endl;
- CPPUNIT_ASSERT_EQUAL(pmt::write_string(tags4[i]), pmt::write_string(expected_tags4[i]));
+ CPPUNIT_ASSERT_EQUAL(tags4[i], expected_tags4[i]);
}
#endif
}
@@ -207,33 +217,33 @@ qa_block_tags::t2 ()
str0 << ann0->name() << ann0->unique_id();
str1 << ann1->name() << ann1->unique_id();
- pmt::pmt_t expected_tags2[12];
- expected_tags2[0] = mp(pmt::from_uint64(0), mp(str1.str()), mp("seq"), mp(0));
- expected_tags2[1] = mp(pmt::from_uint64(0), mp(str0.str()), mp("seq"), mp(0));
- expected_tags2[2] = mp(pmt::from_uint64(0), mp(str0.str()), mp("seq"), mp(1));
- expected_tags2[3] = mp(pmt::from_uint64(10000), mp(str1.str()), mp("seq"), mp(3));
- expected_tags2[4] = mp(pmt::from_uint64(10000), mp(str0.str()), mp("seq"), mp(2));
- expected_tags2[5] = mp(pmt::from_uint64(10000), mp(str0.str()), mp("seq"), mp(3));
- expected_tags2[6] = mp(pmt::from_uint64(20000), mp(str1.str()), mp("seq"), mp(6));
- expected_tags2[7] = mp(pmt::from_uint64(20000), mp(str0.str()), mp("seq"), mp(4));
- expected_tags2[8] = mp(pmt::from_uint64(20000), mp(str0.str()), mp("seq"), mp(5));
- expected_tags2[9] = mp(pmt::from_uint64(30000), mp(str1.str()), mp("seq"), mp(9));
- expected_tags2[10] = mp(pmt::from_uint64(30000), mp(str0.str()), mp("seq"), mp(6));
- expected_tags2[11] = mp(pmt::from_uint64(30000), mp(str0.str()), mp("seq"), mp(7));
-
- pmt::pmt_t expected_tags4[12];
- expected_tags4[0] = mp(pmt::from_uint64(0), mp(str1.str()), mp("seq"), mp(2));
- expected_tags4[1] = mp(pmt::from_uint64(0), mp(str0.str()), mp("seq"), mp(0));
- expected_tags4[2] = mp(pmt::from_uint64(0), mp(str0.str()), mp("seq"), mp(1));
- expected_tags4[3] = mp(pmt::from_uint64(10000), mp(str1.str()), mp("seq"), mp(5));
- expected_tags4[4] = mp(pmt::from_uint64(10000), mp(str0.str()), mp("seq"), mp(2));
- expected_tags4[5] = mp(pmt::from_uint64(10000), mp(str0.str()), mp("seq"), mp(3));
- expected_tags4[6] = mp(pmt::from_uint64(20000), mp(str1.str()), mp("seq"), mp(8));
- expected_tags4[7] = mp(pmt::from_uint64(20000), mp(str0.str()), mp("seq"), mp(4));
- expected_tags4[8] = mp(pmt::from_uint64(20000), mp(str0.str()), mp("seq"), mp(5));
- expected_tags4[9] = mp(pmt::from_uint64(30000), mp(str1.str()), mp("seq"), mp(11));
- expected_tags4[10] = mp(pmt::from_uint64(30000), mp(str0.str()), mp("seq"), mp(6));
- expected_tags4[11] = mp(pmt::from_uint64(30000), mp(str0.str()), mp("seq"), mp(7));
+ gr::tag_t expected_tags2[12];
+ expected_tags2[0] = make_tag(0, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags2[1] = make_tag(0, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags2[2] = make_tag(0, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(1));
+ expected_tags2[3] = make_tag(10000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(3));
+ expected_tags2[4] = make_tag(10000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags2[5] = make_tag(10000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(3));
+ expected_tags2[6] = make_tag(20000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(6));
+ expected_tags2[7] = make_tag(20000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(4));
+ expected_tags2[8] = make_tag(20000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(5));
+ expected_tags2[9] = make_tag(30000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(9));
+ expected_tags2[10] = make_tag(30000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(6));
+ expected_tags2[11] = make_tag(30000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(7));
+
+ gr::tag_t expected_tags4[12];
+ expected_tags4[0] = make_tag(0, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags4[1] = make_tag(0, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags4[2] = make_tag(0, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(1));
+ expected_tags4[3] = make_tag(10000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(5));
+ expected_tags4[4] = make_tag(10000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags4[5] = make_tag(10000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(3));
+ expected_tags4[6] = make_tag(20000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(8));
+ expected_tags4[7] = make_tag(20000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(4));
+ expected_tags4[8] = make_tag(20000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(5));
+ expected_tags4[9] = make_tag(30000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(11));
+ expected_tags4[10] = make_tag(30000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(6));
+ expected_tags4[11] = make_tag(30000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(7));
std::cout << std::endl << "qa_block_tags::t2" << std::endl;
@@ -243,13 +253,13 @@ qa_block_tags::t2 ()
// inconceivable for ann3 to have it wrong.
for(size_t i = 0; i < tags2.size(); i++) {
std::cout << "tags2[" << i << "] = " << tags2[i] << "\t\t" << expected_tags2[i] << std::endl;
- CPPUNIT_ASSERT_EQUAL(pmt::write_string(tags2[i]), pmt::write_string(expected_tags2[i]));
+ CPPUNIT_ASSERT_EQUAL(tags2[i], expected_tags2[i]);
}
std::cout << std::endl;
for(size_t i = 0; i < tags4.size(); i++) {
std::cout << "tags2[" << i << "] = " << tags4[i] << "\t\t" << expected_tags4[i] << std::endl;
- CPPUNIT_ASSERT_EQUAL(pmt::write_string(tags4[i]), pmt::write_string(expected_tags4[i]));
+ CPPUNIT_ASSERT_EQUAL(tags4[i], expected_tags4[i]);
}
#endif
}
@@ -301,39 +311,39 @@ qa_block_tags::t3()
str1 << ann1->name() << ann1->unique_id();
str2 << ann2->name() << ann2->unique_id();
- pmt::pmt_t expected_tags3[8];
- expected_tags3[0] = mp(pmt::from_uint64(0), mp(str1.str()), mp("seq"), mp(0));
- expected_tags3[1] = mp(pmt::from_uint64(0), mp(str0.str()), mp("seq"), mp(0));
- expected_tags3[2] = mp(pmt::from_uint64(10000), mp(str1.str()), mp("seq"), mp(1));
- expected_tags3[3] = mp(pmt::from_uint64(10000), mp(str0.str()), mp("seq"), mp(2));
- expected_tags3[4] = mp(pmt::from_uint64(20000), mp(str1.str()), mp("seq"), mp(2));
- expected_tags3[5] = mp(pmt::from_uint64(20000), mp(str0.str()), mp("seq"), mp(4));
- expected_tags3[6] = mp(pmt::from_uint64(30000), mp(str1.str()), mp("seq"), mp(3));
- expected_tags3[7] = mp(pmt::from_uint64(30000), mp(str0.str()), mp("seq"), mp(6));
-
- pmt::pmt_t expected_tags4[8];
- expected_tags4[0] = mp(pmt::from_uint64(0), mp(str2.str()), mp("seq"), mp(0));
- expected_tags4[1] = mp(pmt::from_uint64(0), mp(str0.str()), mp("seq"), mp(1));
- expected_tags4[2] = mp(pmt::from_uint64(10000), mp(str2.str()), mp("seq"), mp(1));
- expected_tags4[3] = mp(pmt::from_uint64(10000), mp(str0.str()), mp("seq"), mp(3));
- expected_tags4[4] = mp(pmt::from_uint64(20000), mp(str2.str()), mp("seq"), mp(2));
- expected_tags4[5] = mp(pmt::from_uint64(20000), mp(str0.str()), mp("seq"), mp(5));
- expected_tags4[6] = mp(pmt::from_uint64(30000), mp(str2.str()), mp("seq"), mp(3));
- expected_tags4[7] = mp(pmt::from_uint64(30000), mp(str0.str()), mp("seq"), mp(7));
+ gr::tag_t expected_tags3[8];
+ expected_tags3[0] = make_tag(0, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags3[1] = make_tag(0, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags3[2] = make_tag(10000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(1));
+ expected_tags3[3] = make_tag(10000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags3[4] = make_tag(20000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags3[5] = make_tag(20000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(4));
+ expected_tags3[6] = make_tag(30000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(3));
+ expected_tags3[7] = make_tag(30000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(6));
+
+ gr::tag_t expected_tags4[8];
+ expected_tags4[0] = make_tag(0, pmt::mp(str2.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags4[1] = make_tag(0, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(1));
+ expected_tags4[2] = make_tag(10000, pmt::mp(str2.str()), pmt::mp("seq"), pmt::mp(1));
+ expected_tags4[3] = make_tag(10000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(3));
+ expected_tags4[4] = make_tag(20000, pmt::mp(str2.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags4[5] = make_tag(20000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(5));
+ expected_tags4[6] = make_tag(30000, pmt::mp(str2.str()), pmt::mp("seq"), pmt::mp(3));
+ expected_tags4[7] = make_tag(30000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(7));
std::cout << std::endl << "qa_block_tags::t3" << std::endl;
// For annotator 3, we know it gets tags from ann0 and ann1, test this
for(size_t i = 0; i < tags3.size(); i++) {
std::cout << "tags3[" << i << "] = " << tags3[i] << "\t\t" << expected_tags3[i] << std::endl;
- CPPUNIT_ASSERT_EQUAL(pmt::write_string(tags3[i]), pmt::write_string(expected_tags3[i]));
+ CPPUNIT_ASSERT_EQUAL(tags3[i], expected_tags3[i]);
}
// For annotator 4, we know it gets tags from ann0 and ann2, test this
std::cout << std::endl;
for(size_t i = 0; i < tags4.size(); i++) {
std::cout << "tags4[" << i << "] = " << tags4[i] << "\t\t" << expected_tags4[i] << std::endl;
- CPPUNIT_ASSERT_EQUAL(pmt::write_string(tags4[i]), pmt::write_string(expected_tags4[i]));
+ CPPUNIT_ASSERT_EQUAL(tags4[i], expected_tags4[i]);
}
#endif
}
@@ -409,23 +419,23 @@ qa_block_tags::t5()
str1 << ann1->name() << ann1->unique_id();
str2 << ann2->name() << ann2->unique_id();
- pmt_t expected_tags1[5];
- expected_tags1[0] = mp(pmt::from_uint64(0), mp(str0.str()), mp("seq"), mp(0));
- expected_tags1[1] = mp(pmt::from_uint64(10000), mp(str0.str()), mp("seq"), mp(1));
- expected_tags1[2] = mp(pmt::from_uint64(20000), mp(str0.str()), mp("seq"), mp(2));
- expected_tags1[3] = mp(pmt::from_uint64(30000), mp(str0.str()), mp("seq"), mp(3));
-
- pmt_t expected_tags2[10];
- expected_tags2[0] = mp(pmt::from_uint64(0), mp(str1.str()), mp("seq"), mp(0));
- expected_tags2[1] = mp(pmt::from_uint64(0), mp(str0.str()), mp("seq"), mp(0));
- expected_tags2[2] = mp(pmt::from_uint64(1000), mp(str1.str()), mp("seq"), mp(1));
- expected_tags2[3] = mp(pmt::from_uint64(1000), mp(str0.str()), mp("seq"), mp(1));
- expected_tags2[4] = mp(pmt::from_uint64(2000), mp(str1.str()), mp("seq"), mp(2));
- expected_tags2[5] = mp(pmt::from_uint64(2000), mp(str0.str()), mp("seq"), mp(2));
- expected_tags2[6] = mp(pmt::from_uint64(3000), mp(str1.str()), mp("seq"), mp(3));
- expected_tags2[7] = mp(pmt::from_uint64(3000), mp(str0.str()), mp("seq"), mp(3));
- expected_tags2[8] = mp(pmt::from_uint64(4000), mp(str1.str()), mp("seq"), mp(4));
- expected_tags2[9] = mp(pmt::from_uint64(4000), mp(str0.str()), mp("seq"), mp(4));
+ gr::tag_t expected_tags1[5];
+ expected_tags1[0] = make_tag(0, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags1[1] = make_tag(10000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(1));
+ expected_tags1[2] = make_tag(20000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags1[3] = make_tag(30000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(3));
+
+ gr::tag_t expected_tags2[10];
+ expected_tags2[0] = make_tag(0, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags2[1] = make_tag(0, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags2[2] = make_tag(1000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(1));
+ expected_tags2[3] = make_tag(1000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(1));
+ expected_tags2[4] = make_tag(2000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags2[5] = make_tag(2000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags2[6] = make_tag(3000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(3));
+ expected_tags2[7] = make_tag(3000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(3));
+ expected_tags2[8] = make_tag(4000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(4));
+ expected_tags2[9] = make_tag(4000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(4));
std::cout << std::endl << "qa_block_tags::t5" << std::endl;
@@ -433,7 +443,7 @@ qa_block_tags::t5()
std::cout << "tags1.size(): " << tags1.size() << std::endl;
for(size_t i = 0; i < tags1.size(); i++) {
std::cout << "tags1[" << i << "] = " << tags1[i] << "\t\t" << expected_tags1[i] << std::endl;
- CPPUNIT_ASSERT_EQUAL(pmt::write_string(tags1[i]), pmt::write_string(expected_tags1[i]));
+ CPPUNIT_ASSERT_EQUAL(tags1[i], expected_tags1[i]);
}
// annotator 2 gets tags from annotators 0 and 1
@@ -441,7 +451,7 @@ qa_block_tags::t5()
std::cout << "tags2.size(): " << tags2.size() << std::endl;
for(size_t i = 0; i < tags2.size(); i++) {
std::cout << "tags2[" << i << "] = " << tags2[i] << "\t\t" << expected_tags2[i] << std::endl;
- CPPUNIT_ASSERT_EQUAL(pmt::write_string(tags2[i]), pmt::write_string(expected_tags2[i]));
+ CPPUNIT_ASSERT_EQUAL(tags2[i], expected_tags2[i]);
}
#endif
}
diff --git a/gr-blocks/lib/throttle_impl.cc b/gr-blocks/lib/throttle_impl.cc
index f46decee11..7c24f80ae1 100644
--- a/gr-blocks/lib/throttle_impl.cc
+++ b/gr-blocks/lib/throttle_impl.cc
@@ -57,6 +57,14 @@ namespace gr {
{
}
+ bool
+ throttle_impl::start()
+ {
+ d_start = boost::get_system_time();
+ d_total_samples = 0;
+ return block::start();
+ }
+
void
throttle_impl::set_sample_rate(double rate)
{
diff --git a/gr-blocks/lib/throttle_impl.h b/gr-blocks/lib/throttle_impl.h
index c5e43d7564..6afacbba5d 100644
--- a/gr-blocks/lib/throttle_impl.h
+++ b/gr-blocks/lib/throttle_impl.h
@@ -41,6 +41,9 @@ namespace gr {
throttle_impl(size_t itemsize, double samples_per_sec, bool ignore_tags=true);
~throttle_impl();
+ // Overloading gr::block::start to reset timer
+ bool start();
+
void setup_rpc();
void set_sample_rate(double rate);
diff --git a/gr-blocks/lib/udp_sink_impl.cc b/gr-blocks/lib/udp_sink_impl.cc
index ae6488f6dd..6989fdb27c 100644
--- a/gr-blocks/lib/udp_sink_impl.cc
+++ b/gr-blocks/lib/udp_sink_impl.cc
@@ -76,13 +76,12 @@ namespace gr {
std::string s_port = (boost::format("%d")%port).str();
if(host.size() > 0) {
boost::asio::ip::udp::resolver resolver(d_io_service);
- boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(),
- host, s_port,
+ boost::asio::ip::udp::resolver::query query(host, s_port,
boost::asio::ip::resolver_query_base::passive);
d_endpoint = *resolver.resolve(query);
d_socket = new boost::asio::ip::udp::socket(d_io_service);
- d_socket->open(boost::asio::ip::udp::v4());
+ d_socket->open(d_endpoint.protocol());
boost::asio::socket_base::reuse_address roption(true);
d_socket->set_option(roption);
diff --git a/gr-blocks/lib/udp_source_impl.cc b/gr-blocks/lib/udp_source_impl.cc
index c3ab8953e7..ca4018464d 100644
--- a/gr-blocks/lib/udp_source_impl.cc
+++ b/gr-blocks/lib/udp_source_impl.cc
@@ -84,8 +84,7 @@ namespace gr {
if(host.size() > 0) {
boost::asio::ip::udp::resolver resolver(d_io_service);
- boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(),
- d_host, s_port,
+ boost::asio::ip::udp::resolver::query query(d_host, s_port,
boost::asio::ip::resolver_query_base::passive);
d_endpoint = *resolver.resolve(query);
diff --git a/gr-blocks/lib/vector_source_X_impl.cc.t b/gr-blocks/lib/vector_source_X_impl.cc.t
index 93f672bfb9..cb17c70d63 100644
--- a/gr-blocks/lib/vector_source_X_impl.cc.t
+++ b/gr-blocks/lib/vector_source_X_impl.cc.t
@@ -106,7 +106,7 @@ namespace gr {
optr += size;
for(unsigned t = 0; t < d_tags.size(); t++) {
add_item_tag(0, nitems_written(0)+i+d_tags[t].offset,
- d_tags[t].key, d_tags[t].value);
+ d_tags[t].key, d_tags[t].value, d_tags[t].srcid);
}
}
}
diff --git a/gr-blocks/python/blocks/qa_pdu.py b/gr-blocks/python/blocks/qa_pdu.py
index 5a29e04735..bbee3605ba 100755
--- a/gr-blocks/python/blocks/qa_pdu.py
+++ b/gr-blocks/python/blocks/qa_pdu.py
@@ -99,8 +99,6 @@ class test_pdu(gr_unittest.TestCase):
msg = pmt.cons( pmt.PMT_NIL, pmt.init_f32vector(10, src_data))
src.to_basic_block()._post(port, msg)
- src.set_max_noutput_items(5)
-
self.tb.start()
#ideally, would wait until we get ten samples
time.sleep(0.2)
diff --git a/gr-digital/grc/digital_costas_loop_cc.xml b/gr-digital/grc/digital_costas_loop_cc.xml
index 668c43dec6..40db3a4a6f 100644
--- a/gr-digital/grc/digital_costas_loop_cc.xml
+++ b/gr-digital/grc/digital_costas_loop_cc.xml
@@ -5,34 +5,60 @@
###################################################
-->
<block>
- <name>Costas Loop</name>
- <key>digital_costas_loop_cc</key>
- <import>from gnuradio import digital</import>
- <make>digital.costas_loop_cc($w, $order)</make>
- <callback>set_loop_bandwidth($w)</callback>
- <param>
- <name>Loop Bandwidth</name>
- <key>w</key>
- <type>real</type>
- </param>
- <param>
- <name>Order</name>
- <key>order</key>
- <type>int</type>
- </param>
- <sink>
- <name>in</name>
- <type>complex</type>
- </sink>
- <source>
- <name>out</name>
- <type>complex</type>
- </source>
+ <name>Costas Loop</name>
+ <key>digital_costas_loop_cc</key>
+ <import>from gnuradio import digital</import>
+ <make>digital.costas_loop_cc($w, $order, $use_snr)</make>
+ <callback>set_loop_bandwidth($w)</callback>
- <!-- Optional Outputs -->
- <source>
- <name>frequency</name>
- <type>float</type>
- <optional>1</optional>
- </source>
+ <param>
+ <name>Loop Bandwidth</name>
+ <key>w</key>
+ <type>real</type>
+ </param>
+
+ <param>
+ <name>Order</name>
+ <key>order</key>
+ <type>int</type>
+ </param>
+
+ <param>
+ <name>Use SNR</name>
+ <key>use_snr</key>
+ <value>False</value>
+ <type>enum</type>
+ <hide>part</hide>
+ <option>
+ <name>Yes</name>
+ <key>True</key>
+ </option>
+ <option>
+ <name>No</name>
+ <key>False</key>
+ </option>
+ </param>
+
+ <sink>
+ <name>in</name>
+ <type>complex</type>
+ </sink>
+
+ <sink>
+ <name>noise</name>
+ <type>message</type>
+ <optional>1</optional>
+ </sink>
+
+ <source>
+ <name>out</name>
+ <type>complex</type>
+ </source>
+
+ <!-- Optional Outputs -->
+ <source>
+ <name>frequency</name>
+ <type>float</type>
+ <optional>1</optional>
+ </source>
</block>
diff --git a/gr-digital/include/gnuradio/digital/costas_loop_cc.h b/gr-digital/include/gnuradio/digital/costas_loop_cc.h
index d924d969b7..ff5b9b993a 100644
--- a/gr-digital/include/gnuradio/digital/costas_loop_cc.h
+++ b/gr-digital/include/gnuradio/digital/costas_loop_cc.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006,2011,2012 Free Software Foundation, Inc.
+ * Copyright 2006,2011,2012,2014 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -58,6 +58,9 @@ namespace gr {
* The Costas loop can have two output streams:
* \li stream 1 (required) is the baseband I and Q;
* \li stream 2 (optional) is the normalized frequency of the loop
+ *
+ * There is a single optional message input:
+ * \li noise: A noise floor estimate used to calculate the SNR of a sample.
*/
class DIGITAL_API costas_loop_cc
: virtual public sync_block,
@@ -72,8 +75,10 @@ namespace gr {
*
* \param loop_bw internal 2nd order loop bandwidth (~ 2pi/100)
* \param order the loop order, either 2, 4, or 8
+ * \param use_snr Use or ignore SNR estimates (from noise message port)
+ * in measurements; also uses tanh instead of slicing.
*/
- static sptr make(float loop_bw, int order);
+ static sptr make(float loop_bw, int order, bool use_snr=false);
/*!
* Returns the current value of the loop error.
diff --git a/gr-digital/include/gnuradio/digital/ofdm_frame_equalizer_vcvc.h b/gr-digital/include/gnuradio/digital/ofdm_frame_equalizer_vcvc.h
index 2715316a93..be38b6f8ae 100644
--- a/gr-digital/include/gnuradio/digital/ofdm_frame_equalizer_vcvc.h
+++ b/gr-digital/include/gnuradio/digital/ofdm_frame_equalizer_vcvc.h
@@ -58,18 +58,19 @@ namespace gr {
/*!
* \param equalizer The equalizer object that will do the actual work
* \param cp_len Length of the cyclic prefix in samples (required to correct the frequency offset)
- * \param len_tag_key Length tag key
+ * \param tsb_key TSB key
* \param propagate_channel_state If true, the channel state after the last symbol
* will be added to the first symbol as a tag
- * \param fixed_frame_len Set if the frame length is fixed throughout,
- * helps with book keeping.
+ * \param fixed_frame_len Set if the frame length is fixed. When this value is given,
+ * the TSB tag key can be left empty, but it is useful even
+ * when using tagged streams at the input.
*/
static sptr make(
- ofdm_equalizer_base::sptr equalizer,
- int cp_len,
- const std::string &len_tag_key = "frame_len",
- bool propagate_channel_state=false,
- int fixed_frame_len=0
+ ofdm_equalizer_base::sptr equalizer,
+ int cp_len,
+ const std::string &tsb_key="frame_len",
+ bool propagate_channel_state=false,
+ int fixed_frame_len=0
);
};
diff --git a/gr-digital/lib/costas_loop_cc_impl.cc b/gr-digital/lib/costas_loop_cc_impl.cc
index 36f95ac022..a53045ac55 100644
--- a/gr-digital/lib/costas_loop_cc_impl.cc
+++ b/gr-digital/lib/costas_loop_cc_impl.cc
@@ -35,37 +35,52 @@ namespace gr {
namespace digital {
costas_loop_cc::sptr
- costas_loop_cc::make(float loop_bw, int order)
+ costas_loop_cc::make(float loop_bw, int order, bool use_snr)
{
return gnuradio::get_initial_sptr
- (new costas_loop_cc_impl(loop_bw, order));
+ (new costas_loop_cc_impl(loop_bw, order, use_snr));
}
- costas_loop_cc_impl::costas_loop_cc_impl(float loop_bw, int order)
+ costas_loop_cc_impl::costas_loop_cc_impl(float loop_bw, int order, bool use_snr)
: sync_block("costas_loop_cc",
io_signature::make(1, 1, sizeof(gr_complex)),
io_signature::make2(1, 2, sizeof(gr_complex), sizeof(float))),
blocks::control_loop(loop_bw, 1.0, -1.0),
- d_order(order), d_error(0), d_phase_detector(NULL)
+ d_order(order), d_error(0), d_noise(1.0), d_phase_detector(NULL)
{
// Set up the phase detector to use based on the constellation order
switch(d_order) {
case 2:
- d_phase_detector = &costas_loop_cc_impl::phase_detector_2;
+ if(use_snr)
+ d_phase_detector = &costas_loop_cc_impl::phase_detector_snr_2;
+ else
+ d_phase_detector = &costas_loop_cc_impl::phase_detector_2;
break;
case 4:
- d_phase_detector = &costas_loop_cc_impl::phase_detector_4;
+ if(use_snr)
+ d_phase_detector = &costas_loop_cc_impl::phase_detector_snr_4;
+ else
+ d_phase_detector = &costas_loop_cc_impl::phase_detector_4;
break;
case 8:
- d_phase_detector = &costas_loop_cc_impl::phase_detector_8;
+ if(use_snr)
+ d_phase_detector = &costas_loop_cc_impl::phase_detector_snr_8;
+ else
+ d_phase_detector = &costas_loop_cc_impl::phase_detector_8;
break;
default:
throw std::invalid_argument("order must be 2, 4, or 8");
break;
}
+
+ message_port_register_in(pmt::mp("noise"));
+ set_msg_handler(
+ pmt::mp("noise"),
+ boost::bind(&costas_loop_cc_impl::handle_set_noise,
+ this, _1));
}
costas_loop_cc_impl::~costas_loop_cc_impl()
@@ -114,11 +129,50 @@ namespace gr {
}
float
+ costas_loop_cc_impl::phase_detector_snr_8(gr_complex sample) const
+ {
+ float K = (sqrt(2.0) - 1);
+ float snr = abs(sample)*abs(sample) / d_noise;
+ if(fabsf(sample.real()) >= fabsf(sample.imag())) {
+ return ((blocks::tanhf_lut(snr*sample.real()) * sample.imag()) -
+ (blocks::tanhf_lut(snr*sample.imag()) * sample.real() * K));
+ }
+ else {
+ return ((blocks::tanhf_lut(snr*sample.real()) * sample.imag() * K) -
+ (blocks::tanhf_lut(snr*sample.imag()) * sample.real()));
+ }
+ }
+
+ float
+ costas_loop_cc_impl::phase_detector_snr_4(gr_complex sample) const
+ {
+ float snr = abs(sample)*abs(sample) / d_noise;
+ return ((blocks::tanhf_lut(snr*sample.real()) * sample.imag()) -
+ (blocks::tanhf_lut(snr*sample.imag()) * sample.real()));
+ }
+
+ float
+ costas_loop_cc_impl::phase_detector_snr_2(gr_complex sample) const
+ {
+ float snr = abs(sample)*abs(sample) / d_noise;
+ return blocks::tanhf_lut(snr*sample.real()) * sample.imag();
+ }
+
+ float
costas_loop_cc_impl::error() const
{
return d_error;
}
+ void
+ costas_loop_cc_impl::handle_set_noise(pmt::pmt_t msg)
+ {
+ if(pmt::is_real(msg)) {
+ d_noise = pmt::to_double(msg);
+ d_noise = powf(10.0f, d_noise/10.0f);
+ }
+ }
+
int
costas_loop_cc_impl::work(int noutput_items,
gr_vector_const_void_star &input_items,
diff --git a/gr-digital/lib/costas_loop_cc_impl.h b/gr-digital/lib/costas_loop_cc_impl.h
index 665724236b..ebd05e2e93 100644
--- a/gr-digital/lib/costas_loop_cc_impl.h
+++ b/gr-digital/lib/costas_loop_cc_impl.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006,2011,2012 Free Software Foundation, Inc.
+ * Copyright 2006,2011,2012,2014 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -34,33 +34,68 @@ namespace gr {
private:
int d_order;
float d_error;
+ float d_noise;
- /*! \brief the phase detector circuit for 8th-order PSK loops
+ /*! \brief the phase detector circuit for 8th-order PSK loops.
+ *
* \param sample complex sample
* \return the phase error
*/
float phase_detector_8(gr_complex sample) const; // for 8PSK
- /*! \brief the phase detector circuit for fourth-order loops
+ /*! \brief the phase detector circuit for fourth-order loops.
+ *
* \param sample complex sample
* \return the phase error
*/
float phase_detector_4(gr_complex sample) const; // for QPSK
- /*! \brief the phase detector circuit for second-order loops
+ /*! \brief the phase detector circuit for second-order loops.
+ *
* \param sample a complex sample
* \return the phase error
*/
float phase_detector_2(gr_complex sample) const; // for BPSK
+
+ /*! \brief the phase detector circuit for 8th-order PSK
+ * loops. Uses tanh instead of slicing and the noise estimate
+ * from the message port to estimated SNR of the samples.
+ *
+ * \param sample complex sample
+ * \return the phase error
+ */
+ float phase_detector_snr_8(gr_complex sample) const; // for 8PSK
+
+ /*! \brief the phase detector circuit for fourth-order
+ * loops. Uses tanh instead of slicing and the noise estimate
+ * from the message port to estimated SNR of the samples.
+ *
+ * \param sample complex sample
+ * \return the phase error
+ */
+ float phase_detector_snr_4(gr_complex sample) const; // for QPSK
+
+ /*! \brief the phase detector circuit for second-order
+ * loops. Uses tanh instead of slicing and the noise estimate
+ * from the message port to estimated SNR of the samples.
+ *
+ * \param sample a complex sample
+ * \return the phase error
+ */
+ float phase_detector_snr_2(gr_complex sample) const; // for BPSK
+
+
float (costas_loop_cc_impl::*d_phase_detector)(gr_complex sample) const;
public:
- costas_loop_cc_impl(float loop_bw, int order);
+ costas_loop_cc_impl(float loop_bw, int order, bool use_snr=false);
~costas_loop_cc_impl();
float error() const;
+ void handle_set_noise(pmt::pmt_t msg);
+
void setup_rpc();
int work(int noutput_items,
diff --git a/gr-digital/lib/header_payload_demux_impl.cc b/gr-digital/lib/header_payload_demux_impl.cc
index 15308c0be1..160f54036d 100644
--- a/gr-digital/lib/header_payload_demux_impl.cc
+++ b/gr-digital/lib/header_payload_demux_impl.cc
@@ -1,5 +1,5 @@
/* -*- c++ -*- */
-/* Copyright 2012,2013 Free Software Foundation, Inc.
+/* Copyright 2012-2014 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -300,20 +300,19 @@ namespace gr {
}
}
if (d_uses_trigger_tag) {
- std::vector<tag_t> tags;
- get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+noutput_items, d_trigger_tag_key);
- uint64_t min_offset = ULLONG_MAX;
- int tag_index = -1;
- for (unsigned i = 0; i < tags.size(); i++) {
- if (tags[i].offset < min_offset) {
- tag_index = (int) i;
- min_offset = tags[i].offset;
- }
- }
- if (tag_index != -1) {
- remove_item_tag(0, tags[tag_index]);
- return min_offset - nitems_read(0);
- }
+ std::vector<tag_t> tags;
+ get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+noutput_items, d_trigger_tag_key);
+ uint64_t min_offset = ULLONG_MAX;
+ int tag_index = -1;
+ for (unsigned i = 0; i < tags.size(); i++) {
+ if (tags[i].offset < min_offset) {
+ tag_index = (int) i;
+ min_offset = tags[i].offset;
+ }
+ }
+ if (tag_index != -1) {
+ return min_offset - nitems_read(0);
+ }
}
return -1;
} /* find_trigger_signal() */
@@ -388,26 +387,30 @@ namespace gr {
// Copy tags
std::vector<tag_t> tags;
get_tags_in_range(
- tags, 0,
- nitems_read(0),
- nitems_read(0) + n_symbols * (d_items_per_symbol + d_gi)
+ tags, 0,
+ nitems_read(0),
+ nitems_read(0) + n_symbols * (d_items_per_symbol + d_gi)
);
- for (unsigned t = 0; t < tags.size(); t++) {
- int new_offset = tags[t].offset - nitems_read(0);
- if (d_output_symbols) {
- new_offset /= (d_items_per_symbol + d_gi);
- } else if (d_gi) {
- int pos_on_symbol = (new_offset % (d_items_per_symbol + d_gi)) - d_gi;
- if (pos_on_symbol < 0) {
- pos_on_symbol = 0;
- }
- new_offset = (new_offset / (d_items_per_symbol + d_gi)) + pos_on_symbol;
- }
- add_item_tag(port,
- nitems_written(port) + new_offset,
- tags[t].key,
- tags[t].value
- );
+ for (size_t t = 0; t < tags.size(); t++) {
+ // The trigger tag is *not* propagated
+ if (tags[t].key == d_trigger_tag_key) {
+ continue;
+ }
+ int new_offset = tags[t].offset - nitems_read(0);
+ if (d_output_symbols) {
+ new_offset /= (d_items_per_symbol + d_gi);
+ } else if (d_gi) {
+ int pos_on_symbol = (new_offset % (d_items_per_symbol + d_gi)) - d_gi;
+ if (pos_on_symbol < 0) {
+ pos_on_symbol = 0;
+ }
+ new_offset = (new_offset / (d_items_per_symbol + d_gi)) + pos_on_symbol;
+ }
+ add_item_tag(port,
+ nitems_written(port) + new_offset,
+ tags[t].key,
+ tags[t].value
+ );
}
} /* copy_n_symbols() */
diff --git a/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc b/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc
index 4446306a8b..70e840d778 100644
--- a/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc
+++ b/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc
@@ -29,6 +29,9 @@
#define M_TWOPI (2*M_PI)
+static const pmt::pmt_t CARR_OFFSET_KEY = pmt::mp("ofdm_sync_carr_offset");
+static const pmt::pmt_t CHAN_TAPS_KEY = pmt::mp("ofdm_sync_chan_taps");
+
namespace gr {
namespace digital {
@@ -36,14 +39,14 @@ namespace gr {
ofdm_frame_equalizer_vcvc::make(
ofdm_equalizer_base::sptr equalizer,
int cp_len,
- const std::string &len_tag_key,
+ const std::string &tsb_key,
bool propagate_channel_state,
int fixed_frame_len
)
{
return gnuradio::get_initial_sptr (
new ofdm_frame_equalizer_vcvc_impl(
- equalizer, cp_len, len_tag_key, propagate_channel_state, fixed_frame_len
+ equalizer, cp_len, tsb_key, propagate_channel_state, fixed_frame_len
)
);
}
@@ -51,13 +54,13 @@ namespace gr {
ofdm_frame_equalizer_vcvc_impl::ofdm_frame_equalizer_vcvc_impl(
ofdm_equalizer_base::sptr equalizer,
int cp_len,
- const std::string &len_tag_key,
+ const std::string &tsb_key,
bool propagate_channel_state,
int fixed_frame_len
) : tagged_stream_block("ofdm_frame_equalizer_vcvc",
io_signature::make(1, 1, sizeof (gr_complex) * equalizer->fft_len()),
io_signature::make(1, 1, sizeof (gr_complex) * equalizer->fft_len()),
- len_tag_key),
+ tsb_key),
d_fft_len(equalizer->fft_len()),
d_cp_len(cp_len),
d_eq(equalizer),
@@ -65,16 +68,18 @@ namespace gr {
d_fixed_frame_len(fixed_frame_len),
d_channel_state(equalizer->fft_len(), gr_complex(1, 0))
{
- if (len_tag_key.empty() && fixed_frame_len == 0) {
- throw std::invalid_argument("Either specify a length tag or a frame length!");
+ if (tsb_key.empty() && fixed_frame_len == 0) {
+ throw std::invalid_argument("Either specify a TSB tag or a fixed frame length!");
}
if (d_fixed_frame_len < 0) {
- throw std::invalid_argument("Invalid frame length!");
+ throw std::invalid_argument("Invalid frame length!");
}
if (d_fixed_frame_len) {
- set_output_multiple(d_fixed_frame_len);
+ set_output_multiple(d_fixed_frame_len);
}
set_relative_rate(1.0);
+ // Really, we have TPP_ONE_TO_ONE, but the channel state is not propagated
+ set_tag_propagation_policy(TPP_DONT);
}
ofdm_frame_equalizer_vcvc_impl::~ofdm_frame_equalizer_vcvc_impl()
@@ -83,18 +88,17 @@ namespace gr {
void
ofdm_frame_equalizer_vcvc_impl::parse_length_tags(
- const std::vector<std::vector<tag_t> > &tags,
- gr_vector_int &n_input_items_reqd
- ){
+ const std::vector<std::vector<tag_t> > &tags,
+ gr_vector_int &n_input_items_reqd
+ ) {
if (d_fixed_frame_len) {
- n_input_items_reqd[0] = d_fixed_frame_len;
+ n_input_items_reqd[0] = d_fixed_frame_len;
} else {
- for (unsigned k = 0; k < tags[0].size(); k++) {
- if (tags[0][k].key == pmt::string_to_symbol(d_length_tag_key_str)) {
- n_input_items_reqd[0] = pmt::to_long(tags[0][k].value);
- remove_item_tag(0, tags[0][k]);
- }
- }
+ for (unsigned k = 0; k < tags[0].size(); k++) {
+ if (tags[0][k].key == pmt::string_to_symbol(d_length_tag_key_str)) {
+ n_input_items_reqd[0] = pmt::to_long(tags[0][k].value);
+ }
+ }
}
}
@@ -114,15 +118,14 @@ namespace gr {
}
std::vector<tag_t> tags;
- get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+1);
+ get_tags_in_window(tags, 0, 0, 1);
for (unsigned i = 0; i < tags.size(); i++) {
- if (pmt::symbol_to_string(tags[i].key) == "ofdm_sync_chan_taps") {
- d_channel_state = pmt::c32vector_elements(tags[i].value);
- remove_item_tag(0, tags[i]);
- }
- if (pmt::symbol_to_string(tags[i].key) == "ofdm_sync_carr_offset") {
- carrier_offset = pmt::to_long(tags[i].value);
- }
+ if (pmt::symbol_to_string(tags[i].key) == "ofdm_sync_chan_taps") {
+ d_channel_state = pmt::c32vector_elements(tags[i].value);
+ }
+ if (pmt::symbol_to_string(tags[i].key) == "ofdm_sync_carr_offset") {
+ carrier_offset = pmt::to_long(tags[i].value);
+ }
}
// Copy the frame and the channel state vector such that the symbols are shifted to the correct position
@@ -157,7 +160,16 @@ namespace gr {
// Update the channel state regarding the frequency offset
phase_correction = gr_expj(M_TWOPI * carrier_offset * d_cp_len / d_fft_len * frame_len);
for (int k = 0; k < d_fft_len; k++) {
- d_channel_state[k] *= phase_correction;
+ d_channel_state[k] *= phase_correction;
+ }
+
+ // Propagate tags (except for the channel state and the TSB tag)
+ get_tags_in_window(tags, 0, 0, frame_len);
+ for (size_t i = 0; i < tags.size(); i++) {
+ if (tags[i].key != CHAN_TAPS_KEY
+ and tags[i].key != pmt::mp(d_length_tag_key_str)) {
+ add_item_tag(0, tags[i]);
+ }
}
// Housekeeping
diff --git a/gr-digital/lib/ofdm_serializer_vcc_impl.cc b/gr-digital/lib/ofdm_serializer_vcc_impl.cc
index f6c796d3c5..1398dcd2a1 100644
--- a/gr-digital/lib/ofdm_serializer_vcc_impl.cc
+++ b/gr-digital/lib/ofdm_serializer_vcc_impl.cc
@@ -1,5 +1,5 @@
/* -*- c++ -*- */
-/* Copyright 2012 Free Software Foundation, Inc.
+/* Copyright 2012,2014 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -157,55 +157,57 @@ namespace gr {
std::vector<tag_t> tags;
// Packet mode
if (!d_length_tag_key_str.empty()) {
- get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+1);
- for (unsigned i = 0; i < tags.size(); i++) {
- if (tags[i].key == d_carr_offset_key) {
- carr_offset = pmt::to_long(tags[i].value);
- }
- if (tags[i].key == d_packet_len_tag_key) {
- packet_length = pmt::to_long(tags[i].value);
- remove_item_tag(0, tags[i]);
- }
- }
+ get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+1);
+ for (unsigned i = 0; i < tags.size(); i++) {
+ if (tags[i].key == d_carr_offset_key) {
+ carr_offset = pmt::to_long(tags[i].value);
+ }
+ if (tags[i].key == d_packet_len_tag_key) {
+ packet_length = pmt::to_long(tags[i].value);
+ }
+ }
} else {
- // recalc frame length from noutput_items
- frame_length = 0;
- int sym_per_frame = 0;
- while ((sym_per_frame + d_occupied_carriers[(frame_length + 1) % d_occupied_carriers.size()].size()) < (size_t)noutput_items) {
- frame_length++;
- sym_per_frame += d_occupied_carriers[(frame_length + 1) % d_occupied_carriers.size()].size();
- }
+ // recalc frame length from noutput_items
+ frame_length = 0;
+ int sym_per_frame = 0;
+ while ((sym_per_frame + d_occupied_carriers[(frame_length + 1) % d_occupied_carriers.size()].size()) < (size_t)noutput_items) {
+ frame_length++;
+ sym_per_frame += d_occupied_carriers[(frame_length + 1) % d_occupied_carriers.size()].size();
+ }
}
// Copy symbols
int n_out_symbols = 0;
for (int i = 0; i < frame_length; i++) {
- // Copy all tags associated with this input OFDM symbol onto the first output symbol
- get_tags_in_range(tags, 0,
- nitems_read(0)+i,
- nitems_read(0)+i+1
- );
- for (unsigned t = 0; t < tags.size(); t++) {
- add_item_tag(0, nitems_written(0)+n_out_symbols,
- tags[t].key,
- tags[t].value
- );
- }
- for (unsigned k = 0; k < d_occupied_carriers[d_curr_set].size(); k++) {
- out[n_out_symbols++] = in[i * d_fft_len + d_occupied_carriers[d_curr_set][k] + carr_offset];
- }
- if (packet_length && n_out_symbols > packet_length) {
- n_out_symbols = packet_length;
- break;
- }
- d_curr_set = (d_curr_set + 1) % d_occupied_carriers.size();
+ // Copy all tags associated with this input OFDM symbol onto the first output symbol
+ get_tags_in_range(tags, 0,
+ nitems_read(0)+i,
+ nitems_read(0)+i+1
+ );
+ for (size_t t = 0; t < tags.size(); t++) {
+ // The packet length tag is not propagated
+ if (tags[t].key != d_packet_len_tag_key) {
+ add_item_tag(0, nitems_written(0)+n_out_symbols,
+ tags[t].key,
+ tags[t].value
+ );
+ }
+ }
+ for (unsigned k = 0; k < d_occupied_carriers[d_curr_set].size(); k++) {
+ out[n_out_symbols++] = in[i * d_fft_len + d_occupied_carriers[d_curr_set][k] + carr_offset];
+ }
+ if (packet_length && n_out_symbols > packet_length) {
+ n_out_symbols = packet_length;
+ break;
+ }
+ d_curr_set = (d_curr_set + 1) % d_occupied_carriers.size();
}
// Housekeeping
if (d_length_tag_key_str.empty()) {
- consume_each(frame_length);
+ consume_each(frame_length);
} else {
- d_curr_set = d_symbols_skipped;
+ d_curr_set = d_symbols_skipped;
}
return n_out_symbols;
diff --git a/gr-digital/python/digital/qa_costas_loop_cc.py b/gr-digital/python/digital/qa_costas_loop_cc.py
index 9ecb017599..e48f45cc22 100755
--- a/gr-digital/python/digital/qa_costas_loop_cc.py
+++ b/gr-digital/python/digital/qa_costas_loop_cc.py
@@ -1,24 +1,24 @@
#!/usr/bin/env python
#
# Copyright 2011,2013 Free Software Foundation, Inc.
-#
+#
# This file is part of GNU Radio
-#
+#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
-#
+#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
-#
+#
import random
import cmath
@@ -46,7 +46,7 @@ class test_costas_loop_cc(gr_unittest.TestCase):
self.tb.connect(self.src, self.test, self.snk)
self.tb.run()
-
+
expected_result = data
dst_data = self.snk.data()
self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 5)
@@ -77,7 +77,7 @@ class test_costas_loop_cc(gr_unittest.TestCase):
rot = cmath.exp(0.2j) # some small rotation
data = [complex(2*random.randint(0,1)-1, 0) for i in xrange(100)]
-
+
N = 40 # settling time
expected_result = data[N:]
data = [rot*d for d in data]
@@ -89,7 +89,7 @@ class test_costas_loop_cc(gr_unittest.TestCase):
self.tb.run()
dst_data = self.snk.data()[N:]
-
+
# generously compare results; the loop will converge near to, but
# not exactly on, the target data
self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 2)
@@ -103,7 +103,7 @@ class test_costas_loop_cc(gr_unittest.TestCase):
rot = cmath.exp(0.2j) # some small rotation
data = [complex(2*random.randint(0,1)-1, 2*random.randint(0,1)-1)
for i in xrange(100)]
-
+
N = 40 # settling time
expected_result = data[N:]
data = [rot*d for d in data]
@@ -130,7 +130,7 @@ class test_costas_loop_cc(gr_unittest.TestCase):
const = psk.psk_constellation(order)
data = [random.randint(0,7) for i in xrange(100)]
data = [2*rot*const.points()[d] for d in data]
-
+
N = 40 # settling time
expected_result = data[N:]
@@ -144,7 +144,7 @@ class test_costas_loop_cc(gr_unittest.TestCase):
self.tb.run()
dst_data = self.snk.data()[N:]
-
+
# generously compare results; the loop will converge near to, but
# not exactly on, the target data
self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 2)
diff --git a/gr-digital/python/digital/qa_header_payload_demux.py b/gr-digital/python/digital/qa_header_payload_demux.py
index 0b754fe248..8006d4442e 100755
--- a/gr-digital/python/digital/qa_header_payload_demux.py
+++ b/gr-digital/python/digital/qa_header_payload_demux.py
@@ -113,6 +113,86 @@ class qa_header_payload_demux (gr_unittest.TestCase):
]
self.assertEqual(expected_tags_payload, ptags_payload)
+ def test_001_t_tags (self):
+ """ Like the previous test, but use a trigger tag instead of
+ a trigger signal.
+ """
+ n_zeros = 1
+ header = (1, 2, 3)
+ payload = tuple(range(5, 20))
+ data_signal = (0,) * n_zeros + header + payload
+ # Trigger tag
+ trigger_tag = gr.tag_t()
+ trigger_tag.offset = n_zeros
+ trigger_tag.key = pmt.string_to_symbol('detect')
+ trigger_tag.value = pmt.PMT_T
+ # This is dropped:
+ testtag1 = gr.tag_t()
+ testtag1.offset = 0
+ testtag1.key = pmt.string_to_symbol('tag1')
+ testtag1.value = pmt.from_long(0)
+ # This goes on output 0, item 0:
+ testtag2 = gr.tag_t()
+ testtag2.offset = n_zeros
+ testtag2.key = pmt.string_to_symbol('tag2')
+ testtag2.value = pmt.from_long(23)
+ # This goes on output 0, item 2:
+ testtag3 = gr.tag_t()
+ testtag3.offset = n_zeros + len(header) - 1
+ testtag3.key = pmt.string_to_symbol('tag3')
+ testtag3.value = pmt.from_long(42)
+ # This goes on output 1, item 3:
+ testtag4 = gr.tag_t()
+ testtag4.offset = n_zeros + len(header) + 3
+ testtag4.key = pmt.string_to_symbol('tag4')
+ testtag4.value = pmt.from_long(314)
+ data_src = blocks.vector_source_f(
+ data_signal,
+ False,
+ tags=(trigger_tag, testtag1, testtag2, testtag3, testtag4)
+ )
+ hpd = digital.header_payload_demux(
+ len(header), 1, 0, "frame_len", "detect", False, gr.sizeof_float
+ )
+ self.assertEqual(pmt.length(hpd.message_ports_in()), 2) #extra system port defined for you
+ header_sink = blocks.vector_sink_f()
+ payload_sink = blocks.vector_sink_f()
+
+ self.tb.connect(data_src, (hpd, 0))
+ self.tb.connect((hpd, 0), header_sink)
+ self.tb.connect((hpd, 1), payload_sink)
+ self.tb.start()
+ time.sleep(.2) # Need this, otherwise, the next message is ignored
+ hpd.to_basic_block()._post(
+ pmt.intern('header_data'),
+ pmt.from_long(len(payload))
+ )
+ while len(payload_sink.data()) < len(payload):
+ time.sleep(.2)
+ self.tb.stop()
+ self.tb.wait()
+
+ self.assertEqual(header_sink.data(), header)
+ self.assertEqual(payload_sink.data(), payload)
+ ptags_header = []
+ for tag in header_sink.tags():
+ ptag = gr.tag_to_python(tag)
+ ptags_header.append({'key': ptag.key, 'offset': ptag.offset})
+ expected_tags_header = [
+ {'key': 'tag2', 'offset': 0},
+ {'key': 'tag3', 'offset': 2},
+ ]
+ self.assertEqual(expected_tags_header, ptags_header)
+ ptags_payload = []
+ for tag in payload_sink.tags():
+ ptag = gr.tag_to_python(tag)
+ ptags_payload.append({'key': ptag.key, 'offset': ptag.offset})
+ expected_tags_payload = [
+ {'key': 'frame_len', 'offset': 0},
+ {'key': 'tag4', 'offset': 3},
+ ]
+ self.assertEqual(expected_tags_payload, ptags_payload)
+
def test_002_symbols (self):
"""
Same as before, but operate on symbols
diff --git a/gr-digital/python/digital/qa_ofdm_frame_equalizer_vcvc.py b/gr-digital/python/digital/qa_ofdm_frame_equalizer_vcvc.py
index c42fb2b907..1b3ffb7738 100755
--- a/gr-digital/python/digital/qa_ofdm_frame_equalizer_vcvc.py
+++ b/gr-digital/python/digital/qa_ofdm_frame_equalizer_vcvc.py
@@ -72,7 +72,7 @@ class qa_ofdm_frame_equalizer_vcvc (gr_unittest.TestCase):
ptag = gr.tag_to_python(tag)
tag_dict[ptag.key] = ptag.value
expected_dict = {
- 'foo': 42
+ 'foo': 42
}
self.assertEqual(tag_dict, expected_dict)
diff --git a/gr-fec/lib/decoder_impl.cc b/gr-fec/lib/decoder_impl.cc
index ba8a7d000e..62c301d501 100644
--- a/gr-fec/lib/decoder_impl.cc
+++ b/gr-fec/lib/decoder_impl.cc
@@ -95,8 +95,8 @@ namespace gr {
noutput_items/(output_multiple() - d_decoder->get_history()) :
innum;
- GR_LOG_DEBUG(d_debug_logger, boost::format("%1%, %2%, %3%") \
- % outnum % ninput_items[0] % items);
+ //GR_LOG_DEBUG(d_debug_logger, boost::format("%1%, %2%, %3%") \
+ // % outnum % ninput_items[0] % items);
for(int i = 0; i < items; ++i) {
d_decoder->generic_work((void*)(in+(i*d_decoder->get_input_size()*d_input_item_size)),
@@ -109,8 +109,8 @@ namespace gr {
int consumed = static_cast<int>(items/relative_rate()*(output_multiple() - d_decoder->get_history()) + 0.5);
int returned = items*(output_multiple() - d_decoder->get_history());
- GR_LOG_DEBUG(d_debug_logger, boost::format("consumed %1%") % consumed);
- GR_LOG_DEBUG(d_debug_logger, boost::format("returned %1%") % returned);
+ //GR_LOG_DEBUG(d_debug_logger, boost::format("consumed %1%") % consumed);
+ //GR_LOG_DEBUG(d_debug_logger, boost::format("returned %1%") % returned);
consume_each(consumed);
return returned;
diff --git a/gr-fec/lib/encoder_impl.cc b/gr-fec/lib/encoder_impl.cc
index 399bcc41cf..af72f31133 100644
--- a/gr-fec/lib/encoder_impl.cc
+++ b/gr-fec/lib/encoder_impl.cc
@@ -91,8 +91,8 @@ namespace gr {
char *inbuffer = (char*)input_items[0];
char *outbuffer = (char*)output_items[0];
- GR_LOG_DEBUG(d_debug_logger, boost::format("%1%, %2%, %3%") \
- % noutput_items % ninput_items[0] % (noutput_items/output_multiple()));
+ //GR_LOG_DEBUG(d_debug_logger, boost::format("%1%, %2%, %3%") \
+ // % noutput_items % ninput_items[0] % (noutput_items/output_multiple()));
for(int i = 0; i < noutput_items/output_multiple(); i++) {
@@ -100,10 +100,10 @@ namespace gr {
(void*)(outbuffer+(i*d_output_size)));
}
- GR_LOG_DEBUG(d_debug_logger, boost::format("consuming: %1%") \
- % (fixed_rate_noutput_to_ninput(noutput_items)));
- GR_LOG_DEBUG(d_debug_logger, boost::format("returning: %1%") \
- % (noutput_items));
+ //GR_LOG_DEBUG(d_debug_logger, boost::format("consuming: %1%") \
+ // % (fixed_rate_noutput_to_ninput(noutput_items)));
+ //GR_LOG_DEBUG(d_debug_logger, boost::format("returning: %1%") \
+ // % (noutput_items));
consume_each(fixed_rate_noutput_to_ninput(noutput_items));
return noutput_items;
diff --git a/gr-fft/include/gnuradio/fft/window.h b/gr-fft/include/gnuradio/fft/window.h
index c1de1814c7..4b13ddd5c3 100644
--- a/gr-fft/include/gnuradio/fft/window.h
+++ b/gr-fft/include/gnuradio/fft/window.h
@@ -179,32 +179,47 @@ namespace gr {
static std::vector<float> blackmanharris(int ntaps, int atten=92);
/*!
- * \brief Build a Nuttal (or Blackman-Nuttal) window.
+ * \brief Build a Nuttall (or Blackman-Nuttall) window.
*
* See: http://en.wikipedia.org/wiki/Window_function#Blackman.E2.80.93Nuttall_window
*
* \param ntaps Number of coefficients in the window.
*/
+ static std::vector<float> nuttall(int ntaps);
+
+ /*!
+ * Deprecated: use nuttall window instead.
+ */
static std::vector<float> nuttal(int ntaps);
/*!
- * \brief Alias to the Nuttal window.
+ * \brief Alias to the Nuttall window.
*
* \param ntaps Number of coefficients in the window.
*/
+ static std::vector<float> blackman_nuttall(int ntaps);
+
+ /*!
+ * Deprecated: use blackman_nuttall window instead.
+ */
static std::vector<float> blackman_nuttal(int ntaps);
/*!
- * \brief Build a Nuttal continuous first derivative window.
+ * \brief Build a Nuttall continuous first derivative window.
*
* See: http://en.wikipedia.org/wiki/Window_function#Nuttall_window.2C_continuous_first_derivative
*
* \param ntaps Number of coefficients in the window.
*/
+ static std::vector<float> nuttall_cfd(int ntaps);
+
+ /*!
+ * Deprecated: use nuttall_cfd window instead.
+ */
static std::vector<float> nuttal_cfd(int ntaps);
/*!
- * \brief Build a Nuttal continuous first derivative window.
+ * \brief Build a flat top window.
*
* See: http://en.wikipedia.org/wiki/Window_function#Flat_top_window
*
diff --git a/gr-fft/lib/window.cc b/gr-fft/lib/window.cc
index 965b11bf46..126b28978d 100644
--- a/gr-fft/lib/window.cc
+++ b/gr-fft/lib/window.cc
@@ -209,18 +209,36 @@ namespace gr {
std::vector<float>
window::nuttal(int ntaps)
{
+ return nuttall(ntaps);
+ }
+
+ std::vector<float>
+ window::nuttall(int ntaps)
+ {
return coswindow(ntaps, 0.3635819, 0.4891775, 0.1365995, 0.0106411);
}
std::vector<float>
window::blackman_nuttal(int ntaps)
{
- return nuttal(ntaps);
+ return nuttall(ntaps);
+ }
+
+ std::vector<float>
+ window::blackman_nuttall(int ntaps)
+ {
+ return nuttall(ntaps);
}
std::vector<float>
window::nuttal_cfd(int ntaps)
{
+ return nuttall_cfd(ntaps);
+ }
+
+ std::vector<float>
+ window::nuttall_cfd(int ntaps)
+ {
return coswindow(ntaps, 0.355768, 0.487396, 0.144232, 0.012604);
}
diff --git a/gr-qtgui/grc/qtgui_freq_sink_x.xml b/gr-qtgui/grc/qtgui_freq_sink_x.xml
index 94989f5c68..aea46ab4e3 100644
--- a/gr-qtgui/grc/qtgui_freq_sink_x.xml
+++ b/gr-qtgui/grc/qtgui_freq_sink_x.xml
@@ -22,10 +22,14 @@ qtgui.$(type.fcn)(
)
self.$(id).set_update_time($update_time)
self.$(id).set_y_axis($ymin, $ymax)
+self.$(id).set_trigger_mode($tr_mode, $tr_level, $tr_chan, $tr_tag)
self.$(id).enable_autoscale($autoscale)
self.$(id).enable_grid($grid)
self.$(id).set_fft_average($average)
+if $type == type(float()):
+ self.$(id).set_plot_pos_half(not $freqhalf)
+
labels = [$label1, $label2, $label3, $label4, $label5,
$label6, $label7, $label8, $label9, $label10]
widths = [$width1, $width2, $width3, $width4, $width5,
@@ -53,6 +57,7 @@ $(gui_hint()($win))</make>
<param_tab_order>
<tab>General</tab>
+ <tab>Trigger</tab>
<tab>Config</tab>
</param_tab_order>
@@ -80,6 +85,25 @@ $(gui_hint()($win))</make>
<type>int</type>
</param>
+
+ <param>
+ <name>Spectrum Width</name>
+ <key>freqhalf</key>
+ <value>True</value>
+ <type>enum</type>
+ <hide>#if $type() == "float" then 'part' else 'all'#</hide>
+ <option>
+ <name>Full</name>
+ <key>True</key>
+ </option>
+ <option>
+ <name>Half</name>
+ <key>False</key>
+ </option>
+ </param>
+
+
+
<param>
<name>Window Type</name>
<key>wintype</key>
@@ -237,6 +261,63 @@ $(gui_hint()($win))</make>
</option>
</param>
+
+ <!-- Begin Trigger Tab items -->
+ <param>
+ <name>Trigger Mode</name>
+ <key>tr_mode</key>
+ <value>qtgui.TRIG_MODE_FREE</value>
+ <type>enum</type>
+ <hide>part</hide>
+ <option>
+ <name>Free</name>
+ <key>qtgui.TRIG_MODE_FREE</key>
+ </option>
+ <option>
+ <name>Auto</name>
+ <key>qtgui.TRIG_MODE_AUTO</key>
+ </option>
+ <option>
+ <name>Normal</name>
+ <key>qtgui.TRIG_MODE_NORM</key>
+ </option>
+ <option>
+ <name>Tag</name>
+ <key>qtgui.TRIG_MODE_TAG</key>
+ </option>
+ <tab>Trigger</tab>
+ </param>
+
+ <param>
+ <name>Trigger Level</name>
+ <key>tr_level</key>
+ <value>0.0</value>
+ <type>float</type>
+ <hide>part</hide>
+ <tab>Trigger</tab>
+ </param>
+
+ <param>
+ <name>Trigger Channel</name>
+ <key>tr_chan</key>
+ <value>0</value>
+ <type>int</type>
+ <hide>part</hide>
+ <tab>Trigger</tab>
+ </param>
+
+ <param>
+ <name>Trigger Tag Key</name>
+ <key>tr_tag</key>
+ <value>""</value>
+ <type>string</type>
+ <hide>part</hide>
+ <tab>Trigger</tab>
+ </param>
+
+
+
+ <!-- Begin Config Tab items -->
<param>
<name>Line 1 Label</name>
<key>label1</key>
diff --git a/gr-qtgui/grc/qtgui_waterfall_sink_x.xml b/gr-qtgui/grc/qtgui_waterfall_sink_x.xml
index d6e0f5911b..3b6e37e16b 100644
--- a/gr-qtgui/grc/qtgui_waterfall_sink_x.xml
+++ b/gr-qtgui/grc/qtgui_waterfall_sink_x.xml
@@ -23,6 +23,9 @@ qtgui.$(type.fcn)(
self.$(id).set_update_time($update_time)
self.$(id).enable_grid($grid)
+if $type == type(float()):
+ self.$(id).set_plot_pos_half(not $freqhalf)
+
labels = [$label1, $label2, $label3, $label4, $label5,
$label6, $label7, $label8, $label9, $label10]
colors = [$color1, $color2, $color3, $color4, $color5,
@@ -77,6 +80,22 @@ $(gui_hint()($win))</make>
</param>
<param>
+ <name>Spectrum Width</name>
+ <key>freqhalf</key>
+ <value>True</value>
+ <type>enum</type>
+ <hide>#if $type() == "float" then 'part' else 'all'#</hide>
+ <option>
+ <name>Full</name>
+ <key>True</key>
+ </option>
+ <option>
+ <name>Half</name>
+ <key>False</key>
+ </option>
+ </param>
+
+ <param>
<name>Window Type</name>
<key>wintype</key>
<value>firdes.WIN_BLACKMAN_hARRIS</value>
diff --git a/gr-qtgui/include/gnuradio/qtgui/FrequencyDisplayPlot.h b/gr-qtgui/include/gnuradio/qtgui/FrequencyDisplayPlot.h
index ac7dfe8b6d..cb44fbe510 100644
--- a/gr-qtgui/include/gnuradio/qtgui/FrequencyDisplayPlot.h
+++ b/gr-qtgui/include/gnuradio/qtgui/FrequencyDisplayPlot.h
@@ -118,6 +118,8 @@ public slots:
void setAutoScale(bool state);
+ void setPlotPosHalf(bool half);
+
private:
void _resetXAxisPoints();
void _autoScale(double bottom, double top);
@@ -143,6 +145,7 @@ private:
double d_stop_frequency;
double d_ymax;
double d_ymin;
+ bool d_half_freq;
QwtPlotMarker* d_lower_intensity_marker;
QwtPlotMarker* d_upper_intensity_marker;
diff --git a/gr-qtgui/include/gnuradio/qtgui/WaterfallDisplayPlot.h b/gr-qtgui/include/gnuradio/qtgui/WaterfallDisplayPlot.h
index 4fdd065093..37c6183608 100644
--- a/gr-qtgui/include/gnuradio/qtgui/WaterfallDisplayPlot.h
+++ b/gr-qtgui/include/gnuradio/qtgui/WaterfallDisplayPlot.h
@@ -95,6 +95,7 @@ public slots:
void setIntensityColorMapType1(int);
void setUserDefinedLowIntensityColor(QColor);
void setUserDefinedHighIntensityColor(QColor);
+ void setPlotPosHalf(bool half);
signals:
void updatedLowerIntensityLevel(const double);
@@ -106,6 +107,7 @@ private:
double d_start_frequency;
double d_stop_frequency;
int d_xaxis_multiplier;
+ bool d_half_freq;
std::vector<WaterfallData*> d_data;
diff --git a/gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h b/gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h
index d02505c6f6..f49e7b062f 100644
--- a/gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h
+++ b/gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h
@@ -28,6 +28,7 @@
#endif
#include <gnuradio/qtgui/api.h>
+#include <gnuradio/qtgui/trigger_mode.h>
#include <gnuradio/sync_block.h>
#include <qapplication.h>
#include <gnuradio/filter/firdes.h>
@@ -118,6 +119,33 @@ namespace gr {
virtual void set_line_marker(int which, int marker) = 0;
virtual void set_line_alpha(int which, double alpha) = 0;
+ /*!
+ * Set up a trigger for the sink to know when to start
+ * plotting. Useful to isolate events and avoid noise.
+ *
+ * The trigger modes are Free, Auto, Normal, and Tag (see
+ * gr::qtgui::trigger_mode). The first three are like a normal
+ * trigger function. Free means free running with no trigger,
+ * auto will trigger if the trigger event is seen, but will
+ * still plot otherwise, and normal will hold until the trigger
+ * event is observed. The Tag trigger mode allows us to trigger
+ * off a specific stream tag. The tag trigger is based only on
+ * the name of the tag, so when a tag of the given name is seen,
+ * the trigger is activated.
+ *
+ * In auto and normal mode, we look to see if the magnitude of
+ * the any FFT point is over the set level.
+ *
+ * \param mode The trigger_mode: free, auto, normal, or tag.
+ * \param level The magnitude of the trigger even for auto or normal modes.
+ * \param channel Which input channel to use for the trigger events.
+ * \param tag_key The name (as a string) of the tag to trigger off
+ * of if using the tag mode.
+ */
+ virtual void set_trigger_mode(trigger_mode mode,
+ float level, int channel,
+ const std::string &tag_key="") = 0;
+
virtual std::string title() = 0;
virtual std::string line_label(int which) = 0;
virtual std::string line_color(int which) = 0;
diff --git a/gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h b/gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h
index 81f9c0c8c5..ed65d3136c 100644
--- a/gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h
+++ b/gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h
@@ -28,6 +28,7 @@
#endif
#include <gnuradio/qtgui/api.h>
+#include <gnuradio/qtgui/trigger_mode.h>
#include <gnuradio/sync_block.h>
#include <qapplication.h>
#include <gnuradio/filter/firdes.h>
@@ -117,6 +118,40 @@ namespace gr {
virtual void set_line_marker(int which, int marker) = 0;
virtual void set_line_alpha(int which, double alpha) = 0;
+ /*!
+ * Pass "true" to this function to only show the positive half
+ * of the spectrum. By default, this plotter shows the full
+ * spectrum (positive and negative halves).
+ */
+ virtual void set_plot_pos_half(bool half) = 0;
+
+ /*!
+ * Set up a trigger for the sink to know when to start
+ * plotting. Useful to isolate events and avoid noise.
+ *
+ * The trigger modes are Free, Auto, Normal, and Tag (see
+ * gr::qtgui::trigger_mode). The first three are like a normal
+ * trigger function. Free means free running with no trigger,
+ * auto will trigger if the trigger event is seen, but will
+ * still plot otherwise, and normal will hold until the trigger
+ * event is observed. The Tag trigger mode allows us to trigger
+ * off a specific stream tag. The tag trigger is based only on
+ * the name of the tag, so when a tag of the given name is seen,
+ * the trigger is activated.
+ *
+ * In auto and normal mode, we look to see if the magnitude of
+ * the any FFT point is over the set level.
+ *
+ * \param mode The trigger_mode: free, auto, normal, or tag.
+ * \param level The magnitude of the trigger even for auto or normal modes.
+ * \param channel Which input channel to use for the trigger events.
+ * \param tag_key The name (as a string) of the tag to trigger off
+ * of if using the tag mode.
+ */
+ virtual void set_trigger_mode(trigger_mode mode,
+ float level, int channel,
+ const std::string &tag_key="") = 0;
+
virtual std::string title() = 0;
virtual std::string line_label(int which) = 0;
virtual std::string line_color(int which) = 0;
diff --git a/gr-qtgui/include/gnuradio/qtgui/freqdisplayform.h b/gr-qtgui/include/gnuradio/qtgui/freqdisplayform.h
index 7cd077e6f8..744ac3ee90 100644
--- a/gr-qtgui/include/gnuradio/qtgui/freqdisplayform.h
+++ b/gr-qtgui/include/gnuradio/qtgui/freqdisplayform.h
@@ -49,6 +49,13 @@ class FreqDisplayForm : public DisplayForm
float getFFTAverage() const;
gr::filter::firdes::win_type getFFTWindowType() const;
+ // Trigger methods
+ gr::qtgui::trigger_mode getTriggerMode() const;
+ float getTriggerLevel() const;
+ int getTriggerChannel() const;
+ std::string getTriggerTagKey() const;
+
+
// returns the frequency that was last double-clicked on by the user
float getClickedFreq() const;
@@ -69,9 +76,19 @@ public slots:
void setYMax(const QString &m);
void setYMin(const QString &m);
void autoScale(bool en);
+ void setPlotPosHalf(bool half);
void clearMaxHold();
void clearMinHold();
+ // Trigger slots
+ void updateTrigger(gr::qtgui::trigger_mode mode);
+ void setTriggerMode(gr::qtgui::trigger_mode mode);
+ void setTriggerLevel(QString s);
+ void setTriggerLevel(float level);
+ void setTriggerChannel(int chan);
+ void setTriggerTagKey(QString s);
+ void setTriggerTagKey(const std::string &s);
+
private slots:
void newData(const QEvent *updateEvent);
void onPlotPointSelected(const QPointF p);
@@ -93,6 +110,17 @@ private:
FFTAverageMenu *d_avgmenu;
FFTWindowMenu *d_winmenu;
QAction *d_clearmin_act, *d_clearmax_act;
+
+ QMenu *d_triggermenu;
+ TriggerModeMenu *d_tr_mode_menu;
+ PopupMenu *d_tr_level_act;
+ TriggerChannelMenu *d_tr_channel_menu;
+ PopupMenu *d_tr_tag_key_act;
+
+ gr::qtgui::trigger_mode d_trig_mode;
+ float d_trig_level;
+ int d_trig_channel;
+ std::string d_trig_tag_key;
};
#endif /* FREQ_DISPLAY_FORM_H */
diff --git a/gr-qtgui/include/gnuradio/qtgui/waterfall_sink_f.h b/gr-qtgui/include/gnuradio/qtgui/waterfall_sink_f.h
index bbfcc33164..4570ef9d54 100644
--- a/gr-qtgui/include/gnuradio/qtgui/waterfall_sink_f.h
+++ b/gr-qtgui/include/gnuradio/qtgui/waterfall_sink_f.h
@@ -124,6 +124,13 @@ namespace gr {
virtual void set_line_alpha(int which, double alpha) = 0;
virtual void set_color_map(int which, const int color) = 0;
+ /*!
+ * Pass "true" to this function to only show the positive half
+ * of the spectrum. By default, this plotter shows the full
+ * spectrum (positive and negative halves).
+ */
+ virtual void set_plot_pos_half(bool half) = 0;
+
virtual std::string title() = 0;
virtual std::string line_label(int which) = 0;
virtual double line_alpha(int which) = 0;
diff --git a/gr-qtgui/include/gnuradio/qtgui/waterfalldisplayform.h b/gr-qtgui/include/gnuradio/qtgui/waterfalldisplayform.h
index 8017d5ce8f..e885a525b0 100644
--- a/gr-qtgui/include/gnuradio/qtgui/waterfalldisplayform.h
+++ b/gr-qtgui/include/gnuradio/qtgui/waterfalldisplayform.h
@@ -86,6 +86,7 @@ public slots:
const QColor highColor=QColor("white"));
void autoScale(bool en=false);
+ void setPlotPosHalf(bool half);
private slots:
void newData(const QEvent *updateEvent);
diff --git a/gr-qtgui/lib/FrequencyDisplayPlot.cc b/gr-qtgui/lib/FrequencyDisplayPlot.cc
index 12835bcd27..41050edfc2 100644
--- a/gr-qtgui/lib/FrequencyDisplayPlot.cc
+++ b/gr-qtgui/lib/FrequencyDisplayPlot.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2008-2011 Free Software Foundation, Inc.
+ * Copyright 2008-2011,2014 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -94,6 +94,7 @@ FrequencyDisplayPlot::FrequencyDisplayPlot(int nplots, QWidget* parent)
d_min_fft_data = new double[d_numPoints];
d_max_fft_data = new double[d_numPoints];
d_xdata = new double[d_numPoints];
+ d_half_freq = false;
setAxisTitle(QwtPlot::xBottom, "Frequency (Hz)");
setAxisScaleDraw(QwtPlot::xBottom, new FreqDisplayScaleDraw(0));
@@ -279,8 +280,13 @@ FrequencyDisplayPlot::setFrequencyRange(const double centerfreq,
const double bandwidth,
const double units, const std::string &strunits)
{
- double startFreq = (centerfreq - bandwidth/2.0f) / units;
- double stopFreq = (centerfreq + bandwidth/2.0f) / units;
+ double startFreq;
+ double stopFreq = (centerfreq + bandwidth/2.0f) / units;
+ if(d_half_freq)
+ startFreq = 0;
+ else
+ startFreq = (centerfreq - bandwidth/2.0f) / units;
+
d_xdata_multiplier = units;
@@ -346,10 +352,13 @@ FrequencyDisplayPlot::plotNewData(const std::vector<double*> dataPoints,
const double noiseFloorAmplitude, const double peakFrequency,
const double peakAmplitude, const double timeInterval)
{
+ int64_t _npoints_in = d_half_freq ? numDataPoints/2 : numDataPoints;
+ int64_t _in_index = d_half_freq ? _npoints_in : 0;
+
if(!d_stop) {
if(numDataPoints > 0) {
- if(numDataPoints != d_numPoints) {
- d_numPoints = numDataPoints;
+ if(_npoints_in != d_numPoints) {
+ d_numPoints = _npoints_in;
delete[] d_min_fft_data;
delete[] d_max_fft_data;
@@ -383,9 +392,9 @@ FrequencyDisplayPlot::plotNewData(const std::vector<double*> dataPoints,
double bottom=1e20, top=-1e20;
for(int n = 0; n < d_nplots; n++) {
- memcpy(d_ydata[n], dataPoints[n], numDataPoints*sizeof(double));
+ memcpy(d_ydata[n], &(dataPoints[n][_in_index]), _npoints_in*sizeof(double));
- for(int64_t point = 0; point < numDataPoints; point++) {
+ for(int64_t point = 0; point < _npoints_in; point++) {
if(dataPoints[n][point] < d_min_fft_data[point]) {
d_min_fft_data[point] = dataPoints[n][point];
}
@@ -462,6 +471,15 @@ FrequencyDisplayPlot::setAutoScale(bool state)
}
void
+FrequencyDisplayPlot::setPlotPosHalf(bool half)
+{
+ d_half_freq = half;
+ if(half)
+ d_start_frequency = 0;
+}
+
+
+void
FrequencyDisplayPlot::setMaxFFTVisible(const bool visibleFlag)
{
d_max_fft_visible = visibleFlag;
@@ -491,7 +509,7 @@ void
FrequencyDisplayPlot::_resetXAxisPoints()
{
double fft_bin_size = (d_stop_frequency - d_start_frequency)
- / static_cast<double>(d_numPoints-1);
+ / static_cast<double>(d_numPoints);
double freqValue = d_start_frequency;
for(int64_t loc = 0; loc < d_numPoints; loc++) {
d_xdata[loc] = freqValue;
diff --git a/gr-qtgui/lib/WaterfallDisplayPlot.cc b/gr-qtgui/lib/WaterfallDisplayPlot.cc
index eb33cba921..86724fe04d 100644
--- a/gr-qtgui/lib/WaterfallDisplayPlot.cc
+++ b/gr-qtgui/lib/WaterfallDisplayPlot.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2008-2012 Free Software Foundation, Inc.
+ * Copyright 2008-2012,2014 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -139,6 +139,7 @@ WaterfallDisplayPlot::WaterfallDisplayPlot(int nplots, QWidget* parent)
resize(parent->width(), parent->height());
d_numPoints = 1024;
+ d_half_freq = false;
setAxisTitle(QwtPlot::xBottom, "Frequency (Hz)");
setAxisScaleDraw(QwtPlot::xBottom, new FreqDisplayScaleDraw(0));
@@ -225,8 +226,13 @@ WaterfallDisplayPlot::setFrequencyRange(const double centerfreq,
const double bandwidth,
const double units, const std::string &strunits)
{
- double startFreq = (centerfreq - bandwidth/2.0f) / units;
- double stopFreq = (centerfreq + bandwidth/2.0f) / units;
+ double startFreq;
+ double stopFreq = (centerfreq + bandwidth/2.0f) / units;
+ if(d_half_freq)
+ startFreq = 0;
+ else
+ startFreq = (centerfreq - bandwidth/2.0f) / units;
+
d_xaxis_multiplier = units;
@@ -273,10 +279,13 @@ WaterfallDisplayPlot::plotNewData(const std::vector<double*> dataPoints,
const gr::high_res_timer_type timestamp,
const int droppedFrames)
{
+ int64_t _npoints_in = d_half_freq ? numDataPoints/2 : numDataPoints;
+ int64_t _in_index = d_half_freq ? _npoints_in : 0;
+
if(!d_stop) {
if(numDataPoints > 0){
- if(numDataPoints != d_numPoints){
- d_numPoints = numDataPoints;
+ if(_npoints_in != d_numPoints) {
+ d_numPoints = _npoints_in;
resetAxis();
@@ -298,7 +307,8 @@ WaterfallDisplayPlot::plotNewData(const std::vector<double*> dataPoints,
((WaterfallZoomer*)d_zoomer)->setZeroTime(timestamp);
for(int i = 0; i < d_nplots; i++) {
- d_data[i]->addFFTData(dataPoints[i], numDataPoints, droppedFrames);
+ d_data[i]->addFFTData(&(dataPoints[i][_in_index]),
+ _npoints_in, droppedFrames);
d_data[i]->incrementNumLinesToUpdate();
d_spectrogram[i]->invalidateCache();
d_spectrogram[i]->itemChanged();
@@ -596,4 +606,13 @@ WaterfallDisplayPlot::_updateIntensityRangeDisplay()
replot();
}
+void
+WaterfallDisplayPlot::setPlotPosHalf(bool half)
+{
+ d_half_freq = half;
+ if(half)
+ d_start_frequency = 0;
+}
+
+
#endif /* WATERFALL_DISPLAY_PLOT_C */
diff --git a/gr-qtgui/lib/const_sink_c_impl.cc b/gr-qtgui/lib/const_sink_c_impl.cc
index f7bdc01489..10b342dbf5 100644
--- a/gr-qtgui/lib/const_sink_c_impl.cc
+++ b/gr-qtgui/lib/const_sink_c_impl.cc
@@ -498,7 +498,7 @@ namespace gr {
d_index += nitems;
- // If we've have a trigger and a full d_size of items in the buffers, plot.
+ // If we have a trigger and a full d_size of items in the buffers, plot.
if((d_triggered) && (d_index == d_end)) {
// Copy data to be plotted to start of buffers.
for(n = 0; n < d_nconnections; n++) {
diff --git a/gr-qtgui/lib/freq_sink_c_impl.cc b/gr-qtgui/lib/freq_sink_c_impl.cc
index 11e8fc378f..e46b9db865 100644
--- a/gr-qtgui/lib/freq_sink_c_impl.cc
+++ b/gr-qtgui/lib/freq_sink_c_impl.cc
@@ -54,8 +54,8 @@ namespace gr {
int nconnections,
QWidget *parent)
: sync_block("freq_sink_c",
- io_signature::make(1, -1, sizeof(gr_complex)),
- io_signature::make(0, 0, 0)),
+ io_signature::make(nconnections, nconnections, sizeof(gr_complex)),
+ io_signature::make(0, 0, 0)),
d_fftsize(fftsize), d_fftavg(1.0),
d_wintype((filter::firdes::win_type)(wintype)),
d_center_freq(fc), d_bandwidth(bw), d_name(name),
@@ -87,6 +87,11 @@ namespace gr {
volk_get_alignment());
memset(d_fbuf, 0, d_fftsize*sizeof(float));
+ d_tmpbuflen = (unsigned int)(floor(d_fftsize/2.0));
+ d_tmpbuf = (float*)volk_malloc(sizeof(float)*(d_tmpbuflen + 1),
+ volk_get_alignment());
+
+
d_index = 0;
for(int i = 0; i < d_nconnections; i++) {
d_residbufs.push_back((gr_complex*)volk_malloc(d_fftsize*sizeof(gr_complex),
@@ -101,6 +106,8 @@ namespace gr {
buildwindow();
initialize();
+
+ set_trigger_mode(TRIG_MODE_FREE, 0, 0);
}
freq_sink_c_impl::~freq_sink_c_impl()
@@ -114,6 +121,7 @@ namespace gr {
}
delete d_fft;
volk_free(d_fbuf);
+ volk_free(d_tmpbuf);
delete d_argv;
}
@@ -125,15 +133,6 @@ namespace gr {
}
void
- freq_sink_c_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required)
- {
- unsigned int ninputs = ninput_items_required.size();
- for (unsigned int i = 0; i < ninputs; i++) {
- ninput_items_required[i] = std::min(d_fftsize, 8191);
- }
- }
-
- void
freq_sink_c_impl::initialize()
{
if(qApp != NULL) {
@@ -162,6 +161,8 @@ namespace gr {
if(d_name.size() > 0)
set_title(d_name);
+ set_output_multiple(d_fftsize);
+
// initialize update time to 10 times a second
set_update_time(0.1);
}
@@ -303,6 +304,29 @@ namespace gr {
d_main_gui->resize(QSize(width, height));
}
+ void
+ freq_sink_c_impl::set_trigger_mode(trigger_mode mode,
+ float level,
+ int channel,
+ const std::string &tag_key)
+ {
+ gr::thread::scoped_lock lock(d_setlock);
+
+ d_trigger_mode = mode;
+ d_trigger_level = level;
+ d_trigger_channel = channel;
+ d_trigger_tag_key = pmt::intern(tag_key);
+ d_triggered = false;
+ d_trigger_count = 0;
+
+ d_main_gui->setTriggerMode(d_trigger_mode);
+ d_main_gui->setTriggerLevel(d_trigger_level);
+ d_main_gui->setTriggerChannel(d_trigger_channel);
+ d_main_gui->setTriggerTagKey(tag_key);
+
+ _reset();
+ }
+
std::string
freq_sink_c_impl::title()
{
@@ -378,10 +402,26 @@ namespace gr {
void
freq_sink_c_impl::reset()
{
- d_index = 0;
+ gr::thread::scoped_lock lock(d_setlock);
+ _reset();
}
void
+ freq_sink_c_impl::_reset()
+ {
+ d_trigger_count = 0;
+
+ // Reset the trigger.
+ if(d_trigger_mode == TRIG_MODE_FREE) {
+ d_triggered = true;
+ }
+ else {
+ d_triggered = false;
+ }
+ }
+
+
+ void
freq_sink_c_impl::fft(float *data_out, const gr_complex *data_in, int size)
{
if(d_window.size()) {
@@ -398,15 +438,12 @@ namespace gr {
size, 1.0, size);
// Perform shift operation
- unsigned int len = (unsigned int)(floor(size/2.0));
- float *tmp = (float*)malloc(sizeof(float)*len);
- memcpy(tmp, &data_out[0], sizeof(float)*len);
- memcpy(&data_out[0], &data_out[len], sizeof(float)*(size - len));
- memcpy(&data_out[size - len], tmp, sizeof(float)*len);
- free(tmp);
+ memcpy(d_tmpbuf, &data_out[0], sizeof(float)*(d_tmpbuflen + 1));
+ memcpy(&data_out[0], &data_out[size - d_tmpbuflen], sizeof(float)*(d_tmpbuflen));
+ memcpy(&data_out[d_tmpbuflen], d_tmpbuf, sizeof(float)*(d_tmpbuflen + 1));
}
- void
+ bool
freq_sink_c_impl::windowreset()
{
gr::thread::scoped_lock lock(d_setlock);
@@ -416,7 +453,9 @@ namespace gr {
if(d_wintype != newwintype) {
d_wintype = newwintype;
buildwindow();
+ return true;
}
+ return false;
}
void
@@ -428,7 +467,7 @@ namespace gr {
}
}
- void
+ bool
freq_sink_c_impl::fftresize()
{
gr::thread::scoped_lock lock(d_setlock);
@@ -467,7 +506,19 @@ namespace gr {
d_fbuf = (float*)volk_malloc(d_fftsize*sizeof(float),
volk_get_alignment());
memset(d_fbuf, 0, d_fftsize*sizeof(float));
+
+ volk_free(d_tmpbuf);
+ d_tmpbuflen = (unsigned int)(floor(d_fftsize/2.0));
+ d_tmpbuf = (float*)volk_malloc(sizeof(float)*(d_tmpbuflen + 1),
+ volk_get_alignment());
+
+ d_last_time = 0;
+
+ set_output_multiple(d_fftsize);
+
+ return true;
}
+ return false;
}
void
@@ -494,59 +545,121 @@ namespace gr {
}
}
+ void
+ freq_sink_c_impl::_gui_update_trigger()
+ {
+ trigger_mode new_trigger_mode = d_main_gui->getTriggerMode();
+ d_trigger_level = d_main_gui->getTriggerLevel();
+ d_trigger_channel = d_main_gui->getTriggerChannel();
+
+ std::string tagkey = d_main_gui->getTriggerTagKey();
+ d_trigger_tag_key = pmt::intern(tagkey);
+
+ if(new_trigger_mode != d_trigger_mode) {
+ d_trigger_mode = new_trigger_mode;
+ _reset();
+ }
+ }
+
+ void
+ freq_sink_c_impl::_test_trigger_tags(int start, int nitems)
+ {
+ uint64_t nr = nitems_read(d_trigger_channel);
+ std::vector<gr::tag_t> tags;
+ get_tags_in_range(tags, d_trigger_channel,
+ nr+start, nr+start+nitems,
+ d_trigger_tag_key);
+ if(tags.size() > 0) {
+ d_triggered = true;
+ d_index = tags[0].offset - nr;
+ d_trigger_count = 0;
+ }
+ }
+
+ void
+ freq_sink_c_impl::_test_trigger_norm(int nitems, std::vector<double*> inputs)
+ {
+ const double *in = (const double*)inputs[d_trigger_channel];
+ for(int i = 0; i < nitems; i++) {
+ d_trigger_count++;
+
+ // Test if trigger has occurred based on the FFT magnitude and
+ // channel number. Test if any value is > the level (in dBx).
+ if(in[i] > d_trigger_level) {
+ d_triggered = true;
+ d_trigger_count = 0;
+ break;
+ }
+ }
+
+ // If using auto trigger mode, trigger periodically even
+ // without a trigger event.
+ if((d_trigger_mode == TRIG_MODE_AUTO) && (d_trigger_count > d_fftsize)) {
+ d_triggered = true;
+ d_trigger_count = 0;
+ }
+ }
+
int
freq_sink_c_impl::work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
- int j=0;
const gr_complex *in = (const gr_complex*)input_items[0];
// Update the FFT size from the application
- fftresize();
- windowreset();
- check_clicked();
+ bool updated = false;
+ updated |= fftresize();
+ updated |= windowreset();
+ if(updated)
+ return 0;
- for(int i=0; i < noutput_items; i+=d_fftsize) {
- unsigned int datasize = noutput_items - i;
- unsigned int resid = d_fftsize-d_index;
+ check_clicked();
+ _gui_update_trigger();
- // If we have enough input for one full FFT, do it
- if(datasize >= resid) {
+ gr::thread::scoped_lock lock(d_setlock);
+ for(d_index = 0; d_index < noutput_items; d_index+=d_fftsize) {
- if(gr::high_res_timer_now() - d_last_time > d_update_time) {
- for(int n = 0; n < d_nconnections; n++) {
- // Fill up residbuf with d_fftsize number of items
- in = (const gr_complex*)input_items[n];
- memcpy(d_residbufs[n]+d_index, &in[j], sizeof(gr_complex)*resid);
+ if((gr::high_res_timer_now() - d_last_time) > d_update_time) {
- fft(d_fbuf, d_residbufs[n], d_fftsize);
- for(int x = 0; x < d_fftsize; x++) {
- d_magbufs[n][x] = (double)((1.0-d_fftavg)*d_magbufs[n][x] + (d_fftavg)*d_fbuf[x]);
- }
- //volk_32f_convert_64f_a(d_magbufs[n], d_fbuf, d_fftsize);
+ // Trigger off tag, if active
+ if((d_trigger_mode == TRIG_MODE_TAG) && !d_triggered) {
+ _test_trigger_tags(d_index, d_fftsize);
+ if(d_triggered) {
+ // If not enough from tag position, early exit
+ if((d_index + d_fftsize) >= noutput_items)
+ return d_index;
}
+ }
- d_last_time = gr::high_res_timer_now();
- d_qApplication->postEvent(d_main_gui,
- new FreqUpdateEvent(d_magbufs, d_fftsize));
- }
+ // Perform FFT and shift operations into d_magbufs
+ for(int n = 0; n < d_nconnections; n++) {
+ in = (const gr_complex*)input_items[n];
+ memcpy(d_residbufs[n], &in[d_index], sizeof(gr_complex)*d_fftsize);
- d_index = 0;
- j += resid;
- }
- // Otherwise, copy what we received into the residbuf for next time
- else {
- for(int n = 0; n < d_nconnections; n++) {
- in = (const gr_complex*)input_items[n];
- memcpy(d_residbufs[n]+d_index, &in[j], sizeof(gr_complex)*datasize);
- }
- d_index += datasize;
- j += datasize;
- }
+ fft(d_fbuf, d_residbufs[n], d_fftsize);
+ for(int x = 0; x < d_fftsize; x++) {
+ d_magbufs[n][x] = (double)((1.0-d_fftavg)*d_magbufs[n][x] + (d_fftavg)*d_fbuf[x]);
+ }
+ //volk_32f_convert_64f_a(d_magbufs[n], d_fbuf, d_fftsize);
+ }
+
+ // Test trigger off signal power in d_magbufs
+ if((d_trigger_mode == TRIG_MODE_NORM) || (d_trigger_mode == TRIG_MODE_AUTO)) {
+ _test_trigger_norm(d_fftsize, d_magbufs);
+ }
+
+ // If a trigger (FREE always triggers), plot and reset state
+ if(d_triggered) {
+ d_last_time = gr::high_res_timer_now();
+ d_qApplication->postEvent(d_main_gui,
+ new FreqUpdateEvent(d_magbufs, d_fftsize));
+ _reset();
+ }
+ }
}
- return j;
+ return noutput_items;
}
} /* namespace qtgui */
diff --git a/gr-qtgui/lib/freq_sink_c_impl.h b/gr-qtgui/lib/freq_sink_c_impl.h
index dc985c1a99..b5f9cd3d4d 100644
--- a/gr-qtgui/lib/freq_sink_c_impl.h
+++ b/gr-qtgui/lib/freq_sink_c_impl.h
@@ -35,11 +35,10 @@ namespace gr {
class QTGUI_API freq_sink_c_impl : public freq_sink_c
{
private:
- void forecast(int noutput_items, gr_vector_int &ninput_items_required);
-
void initialize();
int d_fftsize;
+ int d_tmpbuflen;
float d_fftavg;
filter::firdes::win_type d_wintype;
std::vector<float> d_window;
@@ -55,6 +54,7 @@ namespace gr {
std::vector<gr_complex*> d_residbufs;
std::vector<double*> d_magbufs;
float *d_fbuf;
+ float *d_tmpbuf;
int d_argc;
char *d_argv;
@@ -64,9 +64,9 @@ namespace gr {
gr::high_res_timer_type d_update_time;
gr::high_res_timer_type d_last_time;
- void windowreset();
+ bool windowreset();
void buildwindow();
- void fftresize();
+ bool fftresize();
void check_clicked();
void fft(float *data_out, const gr_complex *data_in, int size);
@@ -74,6 +74,19 @@ namespace gr {
// The message is a PMT pair (intern('freq'), double(frequency)).
void handle_set_freq(pmt::pmt_t msg);
+ // Members used for triggering scope
+ trigger_mode d_trigger_mode;
+ float d_trigger_level;
+ int d_trigger_channel;
+ pmt::pmt_t d_trigger_tag_key;
+ bool d_triggered;
+ int d_trigger_count;
+
+ void _reset();
+ void _gui_update_trigger();
+ void _test_trigger_tags(int start, int nitems);
+ void _test_trigger_norm(int nitems, std::vector<double*> inputs);
+
public:
freq_sink_c_impl(int size, int wintype,
double fc, double bw,
@@ -112,6 +125,9 @@ namespace gr {
void set_line_style(int which, int style);
void set_line_marker(int which, int marker);
void set_line_alpha(int which, double alpha);
+ void set_trigger_mode(trigger_mode mode,
+ float level, int channel,
+ const std::string &tag_key="");
std::string title();
std::string line_label(int which);
diff --git a/gr-qtgui/lib/freq_sink_f_impl.cc b/gr-qtgui/lib/freq_sink_f_impl.cc
index c0a29becd8..200b009d79 100644
--- a/gr-qtgui/lib/freq_sink_f_impl.cc
+++ b/gr-qtgui/lib/freq_sink_f_impl.cc
@@ -54,8 +54,8 @@ namespace gr {
int nconnections,
QWidget *parent)
: sync_block("freq_sink_f",
- io_signature::make(1, -1, sizeof(float)),
- io_signature::make(0, 0, 0)),
+ io_signature::make(nconnections, nconnections, sizeof(float)),
+ io_signature::make(0, 0, 0)),
d_fftsize(fftsize), d_fftavg(1.0),
d_wintype((filter::firdes::win_type)(wintype)),
d_center_freq(fc), d_bandwidth(bw), d_name(name),
@@ -87,6 +87,10 @@ namespace gr {
volk_get_alignment());
memset(d_fbuf, 0, d_fftsize*sizeof(float));
+ d_tmpbuflen = (unsigned int)(floor(d_fftsize/2.0));
+ d_tmpbuf = (float*)volk_malloc(sizeof(float)*(d_tmpbuflen + 1),
+ volk_get_alignment());
+
d_index = 0;
for(int i = 0; i < d_nconnections; i++) {
d_residbufs.push_back((float*)volk_malloc(d_fftsize*sizeof(float),
@@ -101,6 +105,8 @@ namespace gr {
buildwindow();
initialize();
+
+ set_trigger_mode(TRIG_MODE_FREE, 0, 0);
}
freq_sink_f_impl::~freq_sink_f_impl()
@@ -114,6 +120,7 @@ namespace gr {
}
delete d_fft;
volk_free(d_fbuf);
+ volk_free(d_tmpbuf);
delete d_argv;
}
@@ -125,15 +132,6 @@ namespace gr {
}
void
- freq_sink_f_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required)
- {
- unsigned int ninputs = ninput_items_required.size();
- for (unsigned int i = 0; i < ninputs; i++) {
- ninput_items_required[i] = std::min(d_fftsize, 8191);
- }
- }
-
- void
freq_sink_f_impl::initialize()
{
if(qApp != NULL) {
@@ -162,6 +160,8 @@ namespace gr {
if(d_name.size() > 0)
set_title(d_name);
+ set_output_multiple(d_fftsize);
+
// initialize update time to 10 times a second
set_update_time(0.1);
}
@@ -303,6 +303,35 @@ namespace gr {
d_main_gui->resize(QSize(width, height));
}
+ void
+ freq_sink_f_impl::set_plot_pos_half(bool half)
+ {
+ d_main_gui->setPlotPosHalf(half);
+ }
+
+ void
+ freq_sink_f_impl::set_trigger_mode(trigger_mode mode,
+ float level,
+ int channel,
+ const std::string &tag_key)
+ {
+ gr::thread::scoped_lock lock(d_setlock);
+
+ d_trigger_mode = mode;
+ d_trigger_level = level;
+ d_trigger_channel = channel;
+ d_trigger_tag_key = pmt::intern(tag_key);
+ d_triggered = false;
+ d_trigger_count = 0;
+
+ d_main_gui->setTriggerMode(d_trigger_mode);
+ d_main_gui->setTriggerLevel(d_trigger_level);
+ d_main_gui->setTriggerChannel(d_trigger_channel);
+ d_main_gui->setTriggerTagKey(tag_key);
+
+ _reset();
+ }
+
std::string
freq_sink_f_impl::title()
{
@@ -378,10 +407,25 @@ namespace gr {
void
freq_sink_f_impl::reset()
{
- d_index = 0;
+ gr::thread::scoped_lock lock(d_setlock);
+ _reset();
}
void
+ freq_sink_f_impl::_reset()
+ {
+ d_trigger_count = 0;
+
+ // Reset the trigger.
+ if(d_trigger_mode == TRIG_MODE_FREE) {
+ d_triggered = true;
+ }
+ else {
+ d_triggered = false;
+ }
+ }
+
+ void
freq_sink_f_impl::fft(float *data_out, const float *data_in, int size)
{
// float to complex conversion
@@ -399,15 +443,12 @@ namespace gr {
size, 1.0, size);
// Perform shift operation
- unsigned int len = (unsigned int)(floor(size/2.0));
- float *tmp = (float*)malloc(sizeof(float)*len);
- memcpy(tmp, &data_out[0], sizeof(float)*len);
- memcpy(&data_out[0], &data_out[len], sizeof(float)*(size - len));
- memcpy(&data_out[size - len], tmp, sizeof(float)*len);
- free(tmp);
+ memcpy(d_tmpbuf, &data_out[0], sizeof(float)*(d_tmpbuflen + 1));
+ memcpy(&data_out[0], &data_out[size - d_tmpbuflen], sizeof(float)*d_tmpbuflen);
+ memcpy(&data_out[d_tmpbuflen], d_tmpbuf, sizeof(float)*(d_tmpbuflen + 1));
}
- void
+ bool
freq_sink_f_impl::windowreset()
{
gr::thread::scoped_lock lock(d_setlock);
@@ -417,7 +458,9 @@ namespace gr {
if(d_wintype != newwintype) {
d_wintype = newwintype;
buildwindow();
+ return true;
}
+ return false;
}
void
@@ -429,7 +472,7 @@ namespace gr {
}
}
- void
+ bool
freq_sink_f_impl::fftresize()
{
gr::thread::scoped_lock lock(d_setlock);
@@ -468,7 +511,19 @@ namespace gr {
d_fbuf = (float*)volk_malloc(d_fftsize*sizeof(float),
volk_get_alignment());
memset(d_fbuf, 0, d_fftsize*sizeof(float));
+
+ volk_free(d_tmpbuf);
+ d_tmpbuflen = (unsigned int)(floor(d_fftsize/2.0));
+ d_tmpbuf = (float*)volk_malloc(sizeof(float)*(d_tmpbuflen + 1),
+ volk_get_alignment());
+
+ d_last_time = 0;
+
+ set_output_multiple(d_fftsize);
+
+ return true;
}
+ return false;
}
void
@@ -495,59 +550,121 @@ namespace gr {
}
}
+ void
+ freq_sink_f_impl::_gui_update_trigger()
+ {
+ trigger_mode new_trigger_mode = d_main_gui->getTriggerMode();
+ d_trigger_level = d_main_gui->getTriggerLevel();
+ d_trigger_channel = d_main_gui->getTriggerChannel();
+
+ std::string tagkey = d_main_gui->getTriggerTagKey();
+ d_trigger_tag_key = pmt::intern(tagkey);
+
+ if(new_trigger_mode != d_trigger_mode) {
+ d_trigger_mode = new_trigger_mode;
+ _reset();
+ }
+ }
+
+ void
+ freq_sink_f_impl::_test_trigger_tags(int start, int nitems)
+ {
+ uint64_t nr = nitems_read(d_trigger_channel);
+ std::vector<gr::tag_t> tags;
+ get_tags_in_range(tags, d_trigger_channel,
+ nr+start, nr+start+nitems,
+ d_trigger_tag_key);
+ if(tags.size() > 0) {
+ d_triggered = true;
+ d_index = tags[0].offset - nr;
+ d_trigger_count = 0;
+ }
+ }
+
+ void
+ freq_sink_f_impl::_test_trigger_norm(int nitems, std::vector<double*> inputs)
+ {
+ const double *in = (const double*)inputs[d_trigger_channel];
+ for(int i = 0; i < nitems; i++) {
+ d_trigger_count++;
+
+ // Test if trigger has occurred based on the FFT magnitude and
+ // channel number. Test if any value is > the level (in dBx).
+ if(in[i] > d_trigger_level) {
+ d_triggered = true;
+ d_trigger_count = 0;
+ break;
+ }
+ }
+
+ // If using auto trigger mode, trigger periodically even
+ // without a trigger event.
+ if((d_trigger_mode == TRIG_MODE_AUTO) && (d_trigger_count > d_fftsize)) {
+ d_triggered = true;
+ d_trigger_count = 0;
+ }
+ }
+
int
freq_sink_f_impl::work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
- int j=0;
const float *in = (const float*)input_items[0];
// Update the FFT size from the application
- fftresize();
- windowreset();
+ bool updated = false;
+ updated |= fftresize();
+ updated |= windowreset();
+ if(updated)
+ return 0;
+
check_clicked();
+ _gui_update_trigger();
+
+ gr::thread::scoped_lock lock(d_setlock);
+ for(d_index = 0; d_index < noutput_items; d_index+=d_fftsize) {
- for(int i=0; i < noutput_items; i+=d_fftsize) {
- unsigned int datasize = noutput_items - i;
- unsigned int resid = d_fftsize-d_index;
+ if((gr::high_res_timer_now() - d_last_time) > d_update_time) {
- // If we have enough input for one full FFT, do it
- if(datasize >= resid) {
+ // Trigger off tag, if active
+ if((d_trigger_mode == TRIG_MODE_TAG) && !d_triggered) {
+ _test_trigger_tags(d_index, d_fftsize);
+ if(d_triggered) {
+ // If not enough from tag position, early exit
+ if((d_index + d_fftsize) >= noutput_items)
+ return d_index;
+ }
+ }
- if(gr::high_res_timer_now() - d_last_time > d_update_time) {
- for(int n = 0; n < d_nconnections; n++) {
- // Fill up residbuf with d_fftsize number of items
- in = (const float*)input_items[n];
- memcpy(d_residbufs[n]+d_index, &in[j], sizeof(float)*resid);
+ for(int n = 0; n < d_nconnections; n++) {
+ // Fill up residbuf with d_fftsize number of items
+ in = (const float*)input_items[n];
+ memcpy(d_residbufs[n], &in[d_index], sizeof(float)*d_fftsize);
- fft(d_fbuf, d_residbufs[n], d_fftsize);
- for(int x = 0; x < d_fftsize; x++) {
- d_magbufs[n][x] = (double)((1.0-d_fftavg)*d_magbufs[n][x] + (d_fftavg)*d_fbuf[x]);
- }
- //volk_32f_convert_64f_a(d_magbufs[n], d_fbuf, d_fftsize);
+ fft(d_fbuf, d_residbufs[n], d_fftsize);
+ for(int x = 0; x < d_fftsize; x++) {
+ d_magbufs[n][x] = (double)((1.0-d_fftavg)*d_magbufs[n][x] + (d_fftavg)*d_fbuf[x]);
}
+ //volk_32f_convert_64f_a(d_magbufs[n], d_fbuf, d_fftsize);
+ }
+ // Test trigger off signal power in d_magbufs
+ if((d_trigger_mode == TRIG_MODE_NORM) || (d_trigger_mode == TRIG_MODE_AUTO)) {
+ _test_trigger_norm(d_fftsize, d_magbufs);
+ }
+
+ // If a trigger (FREE always triggers), plot and reset state
+ if(d_triggered) {
d_last_time = gr::high_res_timer_now();
d_qApplication->postEvent(d_main_gui,
new FreqUpdateEvent(d_magbufs, d_fftsize));
+ _reset();
}
-
- d_index = 0;
- j += resid;
- }
- // Otherwise, copy what we received into the residbuf for next time
- else {
- for(int n = 0; n < d_nconnections; n++) {
- in = (const float*)input_items[n];
- memcpy(d_residbufs[n]+d_index, &in[j], sizeof(float)*datasize);
- }
- d_index += datasize;
- j += datasize;
}
}
- return j;
+ return noutput_items;
}
} /* namespace qtgui */
diff --git a/gr-qtgui/lib/freq_sink_f_impl.h b/gr-qtgui/lib/freq_sink_f_impl.h
index 9c4e1e3bcb..1463699319 100644
--- a/gr-qtgui/lib/freq_sink_f_impl.h
+++ b/gr-qtgui/lib/freq_sink_f_impl.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2012 Free Software Foundation, Inc.
+ * Copyright 2012,2014 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -35,11 +35,10 @@ namespace gr {
class QTGUI_API freq_sink_f_impl : public freq_sink_f
{
private:
- void forecast(int noutput_items, gr_vector_int &ninput_items_required);
-
void initialize();
int d_fftsize;
+ int d_tmpbuflen;
float d_fftavg;
filter::firdes::win_type d_wintype;
std::vector<float> d_window;
@@ -55,6 +54,7 @@ namespace gr {
std::vector<float*> d_residbufs;
std::vector<double*> d_magbufs;
float *d_fbuf;
+ float *d_tmpbuf;
int d_argc;
char *d_argv;
@@ -64,9 +64,9 @@ namespace gr {
gr::high_res_timer_type d_update_time;
gr::high_res_timer_type d_last_time;
- void windowreset();
+ bool windowreset();
void buildwindow();
- void fftresize();
+ bool fftresize();
void check_clicked();
void fft(float *data_out, const float *data_in, int size);
@@ -74,6 +74,19 @@ namespace gr {
// The message is a PMT pair (intern('freq'), double(frequency)).
void handle_set_freq(pmt::pmt_t msg);
+ // Members used for triggering scope
+ trigger_mode d_trigger_mode;
+ float d_trigger_level;
+ int d_trigger_channel;
+ pmt::pmt_t d_trigger_tag_key;
+ bool d_triggered;
+ int d_trigger_count;
+
+ void _reset();
+ void _gui_update_trigger();
+ void _test_trigger_tags(int start, int nitems);
+ void _test_trigger_norm(int nitems, std::vector<double*> inputs);
+
public:
freq_sink_f_impl(int size, int wintype,
double fc, double bw,
@@ -111,6 +124,10 @@ namespace gr {
void set_line_style(int which, int style);
void set_line_marker(int which, int marker);
void set_line_alpha(int which, double alpha);
+ void set_plot_pos_half(bool half);
+ void set_trigger_mode(trigger_mode mode,
+ float level, int channel,
+ const std::string &tag_key="");
std::string title();
std::string line_label(int which);
diff --git a/gr-qtgui/lib/freqdisplayform.cc b/gr-qtgui/lib/freqdisplayform.cc
index ccc7fe9e07..d7fa1563fa 100644
--- a/gr-qtgui/lib/freqdisplayform.cc
+++ b/gr-qtgui/lib/freqdisplayform.cc
@@ -74,6 +74,37 @@ FreqDisplayForm::FreqDisplayForm(int nplots, QWidget* parent)
connect(d_clearmin_act, SIGNAL(triggered()),
this, SLOT(clearMinHold()));
+ // Set up the trigger menu
+ d_triggermenu = new QMenu("Trigger", this);
+ d_tr_mode_menu = new TriggerModeMenu(this);
+ d_tr_level_act = new PopupMenu("Level", this);
+ d_tr_channel_menu = new TriggerChannelMenu(nplots, this);
+ d_tr_tag_key_act = new PopupMenu("Tag Key", this);
+ d_triggermenu->addMenu(d_tr_mode_menu);
+ d_triggermenu->addAction(d_tr_level_act);
+ d_triggermenu->addMenu(d_tr_channel_menu);
+ d_triggermenu->addAction(d_tr_tag_key_act);
+ d_menu->addMenu(d_triggermenu);
+
+ setTriggerMode(gr::qtgui::TRIG_MODE_FREE);
+ connect(d_tr_mode_menu, SIGNAL(whichTrigger(gr::qtgui::trigger_mode)),
+ this, SLOT(setTriggerMode(gr::qtgui::trigger_mode)));
+ // updates trigger state by calling set level or set tag key.
+ connect(d_tr_mode_menu, SIGNAL(whichTrigger(gr::qtgui::trigger_mode)),
+ this, SLOT(updateTrigger(gr::qtgui::trigger_mode)));
+
+ setTriggerLevel(0);
+ connect(d_tr_level_act, SIGNAL(whichTrigger(QString)),
+ this, SLOT(setTriggerLevel(QString)));
+
+ setTriggerChannel(0);
+ connect(d_tr_channel_menu, SIGNAL(whichTrigger(int)),
+ this, SLOT(setTriggerChannel(int)));
+
+ setTriggerTagKey(std::string(""));
+ connect(d_tr_tag_key_act, SIGNAL(whichTrigger(QString)),
+ this, SLOT(setTriggerTagKey(QString)));
+
Reset();
connect(d_display_plot, SIGNAL(plotPointSelected(const QPointF)),
@@ -222,6 +253,13 @@ FreqDisplayForm::autoScale(bool en)
}
void
+FreqDisplayForm::setPlotPosHalf(bool half)
+{
+ getPlot()->setPlotPosHalf(half);
+ getPlot()->replot();
+}
+
+void
FreqDisplayForm::clearMaxHold()
{
getPlot()->clearMaxData();
@@ -257,3 +295,84 @@ FreqDisplayForm::getClickedFreq() const
{
return d_clicked_freq;
}
+
+
+/********************************************************************
+ * TRIGGER METHODS
+ *******************************************************************/
+
+void
+FreqDisplayForm::setTriggerMode(gr::qtgui::trigger_mode mode)
+{
+ d_trig_mode = mode;
+ d_tr_mode_menu->getAction(mode)->setChecked(true);
+}
+
+void
+FreqDisplayForm::updateTrigger(gr::qtgui::trigger_mode mode)
+{
+ // If auto or normal mode, popup trigger level box to set
+ if((d_trig_mode == gr::qtgui::TRIG_MODE_AUTO) || (d_trig_mode == gr::qtgui::TRIG_MODE_NORM))
+ d_tr_level_act->activate(QAction::Trigger);
+
+ // if tag mode, popup tag key box to set
+ if(d_trig_mode == gr::qtgui::TRIG_MODE_TAG)
+ d_tr_tag_key_act->activate(QAction::Trigger);
+}
+
+gr::qtgui::trigger_mode
+FreqDisplayForm::getTriggerMode() const
+{
+ return d_trig_mode;
+}
+
+void
+FreqDisplayForm::setTriggerLevel(QString s)
+{
+ d_trig_level = s.toFloat();
+}
+
+void
+FreqDisplayForm::setTriggerLevel(float level)
+{
+ d_trig_level = level;
+ d_tr_level_act->setText(QString().setNum(d_trig_level));
+}
+
+float
+FreqDisplayForm::getTriggerLevel() const
+{
+ return d_trig_level;
+}
+
+void
+FreqDisplayForm::setTriggerChannel(int channel)
+{
+ d_trig_channel = channel;
+ d_tr_channel_menu->getAction(d_trig_channel)->setChecked(true);
+}
+
+int
+FreqDisplayForm::getTriggerChannel() const
+{
+ return d_trig_channel;
+}
+
+void
+FreqDisplayForm::setTriggerTagKey(QString s)
+{
+ d_trig_tag_key = s.toStdString();
+}
+
+void
+FreqDisplayForm::setTriggerTagKey(const std::string &key)
+{
+ d_trig_tag_key = key;
+ d_tr_tag_key_act->setText(QString().fromStdString(d_trig_tag_key));
+}
+
+std::string
+FreqDisplayForm::getTriggerTagKey() const
+{
+ return d_trig_tag_key;
+}
diff --git a/gr-qtgui/lib/waterfall_sink_f_impl.cc b/gr-qtgui/lib/waterfall_sink_f_impl.cc
index 5667acf2e7..0f7f9e0437 100644
--- a/gr-qtgui/lib/waterfall_sink_f_impl.cc
+++ b/gr-qtgui/lib/waterfall_sink_f_impl.cc
@@ -53,8 +53,8 @@ namespace gr {
int nconnections,
QWidget *parent)
: sync_block("waterfall_sink_f",
- io_signature::make(1, -1, sizeof(float)),
- io_signature::make(0, 0, 0)),
+ io_signature::make(1, -1, sizeof(float)),
+ io_signature::make(0, 0, 0)),
d_fftsize(fftsize), d_fftavg(1.0),
d_wintype((filter::firdes::win_type)(wintype)),
d_center_freq(fc), d_bandwidth(bw), d_name(name),
@@ -107,8 +107,8 @@ namespace gr {
d_main_gui->close();
for(int i = 0; i < d_nconnections; i++) {
- volk_free(d_residbufs[i]);
- volk_free(d_magbufs[i]);
+ volk_free(d_residbufs[i]);
+ volk_free(d_magbufs[i]);
}
delete d_fft;
volk_free(d_fbuf);
@@ -127,7 +127,7 @@ namespace gr {
{
unsigned int ninputs = ninput_items_required.size();
for (unsigned int i = 0; i < ninputs; i++) {
- ninput_items_required[i] = std::min(d_fftsize, 8191);
+ ninput_items_required[i] = std::min(d_fftsize, 8191);
}
}
@@ -135,14 +135,14 @@ namespace gr {
waterfall_sink_f_impl::initialize()
{
if(qApp != NULL) {
- d_qApplication = qApp;
+ d_qApplication = qApp;
}
else {
#if QT_VERSION >= 0x040500
std::string style = prefs::singleton()->get_string("qtgui", "style", "raster");
QApplication::setGraphicsSystem(QString(style.c_str()));
#endif
- d_qApplication = new QApplication(d_argc, &d_argv);
+ d_qApplication = new QApplication(d_argc, &d_argv);
}
// If a style sheet is set in the prefs file, enable it here.
@@ -290,6 +290,12 @@ namespace gr {
d_main_gui->resize(QSize(width, height));
}
+ void
+ waterfall_sink_f_impl::set_plot_pos_half(bool half)
+ {
+ d_main_gui->setPlotPosHalf(half);
+ }
+
std::string
waterfall_sink_f_impl::title()
{
@@ -398,7 +404,8 @@ namespace gr {
{
gr::thread::scoped_lock lock(d_setlock);
- int newfftsize = d_fftsize;
+ int newfftsize = d_main_gui->getFFTSize();
+ d_fftavg = d_main_gui->getFFTAverage();
if(newfftsize != d_fftsize) {
diff --git a/gr-qtgui/lib/waterfall_sink_f_impl.h b/gr-qtgui/lib/waterfall_sink_f_impl.h
index d783f31d14..ca6e3f4264 100644
--- a/gr-qtgui/lib/waterfall_sink_f_impl.h
+++ b/gr-qtgui/lib/waterfall_sink_f_impl.h
@@ -110,6 +110,7 @@ namespace gr {
void set_line_label(int which, const std::string &label);
void set_line_alpha(int which, double alpha);
void set_color_map(int which, const int color);
+ void set_plot_pos_half(bool half);
std::string title();
std::string line_label(int which);
diff --git a/gr-qtgui/lib/waterfalldisplayform.cc b/gr-qtgui/lib/waterfalldisplayform.cc
index fdf09d9180..c1dd8f7aab 100644
--- a/gr-qtgui/lib/waterfalldisplayform.cc
+++ b/gr-qtgui/lib/waterfalldisplayform.cc
@@ -330,3 +330,10 @@ WaterfallDisplayForm::getClickedFreq() const
{
return d_clicked_freq;
}
+
+void
+WaterfallDisplayForm::setPlotPosHalf(bool half)
+{
+ getPlot()->setPlotPosHalf(half);
+ getPlot()->replot();
+}
diff --git a/gr-trellis/doc/gr-trellis.xml b/gr-trellis/doc/gr-trellis.xml
index 6ffbb9ec2c..aabf9ad535 100644
--- a/gr-trellis/doc/gr-trellis.xml
+++ b/gr-trellis/doc/gr-trellis.xml
@@ -176,8 +176,8 @@ private:
int d_O;
std::vector&lt;int&gt; d_NS;
std::vector&lt;int&gt; d_OS;
- std::vector&lt;int&gt; d_PS;
- std::vector&lt;int&gt; d_PI;
+ std::vector&lt; std::vector&lt; int&gt; &gt; d_PS;
+ std::vector&lt; std::vector&lt; int&gt; &gt; d_PI;
std::vector&lt;int&gt; d_TMi;
std::vector&lt;int&gt; d_TMl;
void generate_PS_PI ();
@@ -195,8 +195,8 @@ public:
int O () const { return d_O; }
const std::vector&lt;int&gt; &amp; NS () const { return d_NS; }
const std::vector&lt;int&gt; &amp; OS () const { return d_OS; }
- const std::vector&lt;int&gt; &amp; PS () const { return d_PS; }
- const std::vector&lt;int&gt; &amp; PI () const { return d_PI; }
+ const std::vector&lt; std::vector&lt; int&gt; &gt; &amp; PS () const { return d_PS; }
+ const std::vector&lt; std::vector&lt; int&gt; &gt; &amp; PI () const { return d_PI; }
const std::vector&lt;int&gt; &amp; TMi () const { return d_TMi; }
const std::vector&lt;int&gt; &amp; TMl () const { return d_TMl; }
};
diff --git a/gr-trellis/examples/grc/CMakeLists.txt b/gr-trellis/examples/grc/CMakeLists.txt
index 35280d515f..c5d4fc8965 100644
--- a/gr-trellis/examples/grc/CMakeLists.txt
+++ b/gr-trellis/examples/grc/CMakeLists.txt
@@ -20,13 +20,18 @@
## Configure GRC examples to point to the right fsm_files directory
set(FSM_FILE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${GR_PKG_TRELLIS_EXAMPLES_DIR}/fsm_files/")
configure_file(
- "${CMAKE_CURRENT_SOURCE_DIR}/pccc.grc"
- "${CMAKE_CURRENT_BINARY_DIR}/pccc.grc"
+ "${CMAKE_CURRENT_SOURCE_DIR}/tcm.grc"
+ "${CMAKE_CURRENT_BINARY_DIR}/tcm.grc"
+)
+
+configure_file(
+ "${CMAKE_CURRENT_SOURCE_DIR}/viterbi_equalization.grc"
+ "${CMAKE_CURRENT_BINARY_DIR}/viterbi_equalization.grc"
)
configure_file(
- "${CMAKE_CURRENT_SOURCE_DIR}/pccc1.grc"
- "${CMAKE_CURRENT_BINARY_DIR}/pccc1.grc"
+ "${CMAKE_CURRENT_SOURCE_DIR}/turbo_equalization.grc"
+ "${CMAKE_CURRENT_BINARY_DIR}/turbo_equalization.grc"
)
configure_file(
@@ -35,8 +40,8 @@ configure_file(
)
configure_file(
- "${CMAKE_CURRENT_SOURCE_DIR}/sccc1.grc"
- "${CMAKE_CURRENT_BINARY_DIR}/sccc1.grc"
+ "${CMAKE_CURRENT_SOURCE_DIR}/pccc.grc"
+ "${CMAKE_CURRENT_BINARY_DIR}/pccc.grc"
)
configure_file(
@@ -46,11 +51,12 @@ configure_file(
install(
FILES
- ${CMAKE_CURRENT_BINARY_DIR}/interference_cancellation.grc
- ${CMAKE_CURRENT_BINARY_DIR}/pccc.grc
- ${CMAKE_CURRENT_BINARY_DIR}/pccc1.grc
- ${CMAKE_CURRENT_BINARY_DIR}/sccc1.grc
+ ${CMAKE_CURRENT_BINARY_DIR}/tcm.grc
+ ${CMAKE_CURRENT_BINARY_DIR}/viterbi_equalization.grc
+ ${CMAKE_CURRENT_BINARY_DIR}/turbo_equalization.grc
${CMAKE_CURRENT_BINARY_DIR}/sccc.grc
+ ${CMAKE_CURRENT_BINARY_DIR}/pccc.grc
+ ${CMAKE_CURRENT_BINARY_DIR}/interference_cancellation.grc
readme.txt
DESTINATION ${GR_PKG_TRELLIS_EXAMPLES_DIR}
COMPONENT "trellis-examples"
diff --git a/gr-trellis/examples/grc/interference_cancellation.grc b/gr-trellis/examples/grc/interference_cancellation.grc
index 2ccc723235..1dbcf69b86 100644
--- a/gr-trellis/examples/grc/interference_cancellation.grc
+++ b/gr-trellis/examples/grc/interference_cancellation.grc
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='ASCII'?>
<flow_graph>
- <timestamp>Mon Jul 28 14:00:18 2014</timestamp>
+ <timestamp>Fri Sep 26 18:21:00 2014</timestamp>
<block>
<key>options</key>
<param>
@@ -29,7 +29,7 @@
</param>
<param>
<key>generate_options</key>
- <value>qt_gui</value>
+ <value>wx_gui</value>
</param>
<param>
<key>category</key>
@@ -52,10 +52,6 @@
<value></value>
</param>
<param>
- <key>alias</key>
- <value></value>
- </param>
- <param>
<key>_coordinate</key>
<value>(10, 10)</value>
</param>
@@ -79,12 +75,8 @@
<value>"@FSM_FILE_INSTALL_DIR@"</value>
</param>
<param>
- <key>alias</key>
- <value></value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(660, 11)</value>
+ <value>(871, 14)</value>
</param>
<param>
<key>_rotation</key>
@@ -95,7 +87,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>block</value>
+ <value>R</value>
</param>
<param>
<key>_enabled</key>
@@ -103,15 +95,11 @@
</param>
<param>
<key>value</key>
- <value>1000</value>
- </param>
- <param>
- <key>alias</key>
- <value></value>
+ <value>100e3</value>
</param>
<param>
<key>_coordinate</key>
- <value>(583, 10)</value>
+ <value>(748, 12)</value>
</param>
<param>
<key>_rotation</key>
@@ -122,7 +110,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>R</value>
+ <value>noisevar</value>
</param>
<param>
<key>_enabled</key>
@@ -130,15 +118,11 @@
</param>
<param>
<key>value</key>
- <value>100e3</value>
- </param>
- <param>
- <key>alias</key>
- <value></value>
+ <value>10**(-snr_db/10)</value>
</param>
<param>
<key>_coordinate</key>
- <value>(502, 10)</value>
+ <value>(637, 13)</value>
</param>
<param>
<key>_rotation</key>
@@ -149,7 +133,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>noisevar</value>
+ <value>fsm1</value>
</param>
<param>
<key>_enabled</key>
@@ -157,15 +141,11 @@
</param>
<param>
<key>value</key>
- <value>10**(-snr_db/10)</value>
- </param>
- <param>
- <key>alias</key>
- <value></value>
+ <value>"awgn1o2_16.fsm"</value>
</param>
<param>
<key>_coordinate</key>
- <value>(428, 10)</value>
+ <value>(849, 87)</value>
</param>
<param>
<key>_rotation</key>
@@ -173,54 +153,45 @@
</param>
</block>
<block>
- <key>analog_random_source_x</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>analog_random_source_x_0</value>
+ <value>fsm2</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>short</value>
+ <key>value</key>
+ <value>"awgn1o2_4.fsm"</value>
</param>
<param>
- <key>min</key>
- <value>0</value>
+ <key>_coordinate</key>
+ <value>(849, 153)</value>
</param>
<param>
- <key>max</key>
- <value>2</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>variable</key>
<param>
- <key>num_samps</key>
- <value>1000</value>
+ <key>id</key>
+ <value>block</value>
</param>
<param>
- <key>repeat</key>
+ <key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>alias</key>
- <value></value>
- </param>
- <param>
- <key>affinity</key>
- <value></value>
- </param>
- <param>
- <key>minoutbuf</key>
- <value>0</value>
- </param>
- <param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>value</key>
+ <value>1000</value>
</param>
<param>
<key>_coordinate</key>
- <value>(21, 170)</value>
+ <value>(752, 85)</value>
</param>
<param>
<key>_rotation</key>
@@ -228,38 +199,34 @@
</param>
</block>
<block>
- <key>analog_random_source_x</key>
+ <key>digital_chunks_to_symbols_xx</key>
<param>
<key>id</key>
- <value>analog_random_source_x_1</value>
+ <value>digital_chunks_to_symbols_xx_0_0_1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>short</value>
- </param>
- <param>
- <key>min</key>
- <value>0</value>
+ <key>in_type</key>
+ <value>byte</value>
</param>
<param>
- <key>max</key>
- <value>2</value>
+ <key>out_type</key>
+ <value>complex</value>
</param>
<param>
- <key>num_samps</key>
- <value>1000</value>
+ <key>symbol_table</key>
+ <value>1,1j,-1j,-1</value>
</param>
<param>
- <key>repeat</key>
- <value>True</value>
+ <key>dimension</key>
+ <value>1</value>
</param>
<param>
- <key>alias</key>
- <value></value>
+ <key>num_ports</key>
+ <value>1</value>
</param>
<param>
<key>affinity</key>
@@ -270,12 +237,8 @@
<value>0</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(25, 291)</value>
+ <value>(408, 1719)</value>
</param>
<param>
<key>_rotation</key>
@@ -283,46 +246,22 @@
</param>
</block>
<block>
- <key>blocks_sub_xx</key>
+ <key>virtual_source</key>
<param>
<key>id</key>
- <value>blocks_sub_xx_0</value>
+ <value>virtual_source_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>short</value>
- </param>
- <param>
- <key>vlen</key>
- <value>1</value>
- </param>
- <param>
- <key>num_inputs</key>
- <value>2</value>
- </param>
- <param>
- <key>alias</key>
- <value></value>
- </param>
- <param>
- <key>affinity</key>
- <value></value>
- </param>
- <param>
- <key>minoutbuf</key>
- <value>0</value>
- </param>
- <param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>stream_id</key>
+ <value>user1</value>
</param>
<param>
<key>_coordinate</key>
- <value>(536, 529)</value>
+ <value>(356, 1844)</value>
</param>
<param>
<key>_rotation</key>
@@ -330,46 +269,22 @@
</param>
</block>
<block>
- <key>blocks_multiply_xx</key>
+ <key>virtual_source</key>
<param>
<key>id</key>
- <value>blocks_multiply_xx_0</value>
+ <value>virtual_source_0_2_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>short</value>
- </param>
- <param>
- <key>num_inputs</key>
- <value>2</value>
- </param>
- <param>
- <key>vlen</key>
- <value>1</value>
- </param>
- <param>
- <key>alias</key>
- <value></value>
- </param>
- <param>
- <key>affinity</key>
- <value></value>
- </param>
- <param>
- <key>minoutbuf</key>
- <value>0</value>
- </param>
- <param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>stream_id</key>
+ <value>user2_est</value>
</param>
<param>
<key>_coordinate</key>
- <value>(771, 525)</value>
+ <value>(10, 1649)</value>
</param>
<param>
<key>_rotation</key>
@@ -380,7 +295,7 @@
<key>blocks_sub_xx</key>
<param>
<key>id</key>
- <value>blocks_sub_xx_3</value>
+ <value>blocks_sub_xx_2_0</value>
</param>
<param>
<key>_enabled</key>
@@ -388,7 +303,7 @@
</param>
<param>
<key>type</key>
- <value>short</value>
+ <value>complex</value>
</param>
<param>
<key>vlen</key>
@@ -399,10 +314,6 @@
<value>2</value>
</param>
<param>
- <key>alias</key>
- <value></value>
- </param>
- <param>
<key>affinity</key>
<value></value>
</param>
@@ -411,12 +322,8 @@
<value>0</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(535, 792)</value>
+ <value>(963, 1695)</value>
</param>
<param>
<key>_rotation</key>
@@ -424,46 +331,22 @@
</param>
</block>
<block>
- <key>blocks_sub_xx</key>
+ <key>virtual_source</key>
<param>
<key>id</key>
- <value>blocks_sub_xx_2</value>
+ <value>virtual_source_0_1_2</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>complex</value>
- </param>
- <param>
- <key>vlen</key>
- <value>1</value>
- </param>
- <param>
- <key>num_inputs</key>
- <value>2</value>
- </param>
- <param>
- <key>alias</key>
- <value></value>
- </param>
- <param>
- <key>affinity</key>
- <value></value>
- </param>
- <param>
- <key>minoutbuf</key>
- <value>0</value>
- </param>
- <param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>stream_id</key>
+ <value>observation</value>
</param>
<param>
<key>_coordinate</key>
- <value>(944, 978)</value>
+ <value>(705, 1660)</value>
</param>
<param>
<key>_rotation</key>
@@ -471,10 +354,10 @@
</param>
</block>
<block>
- <key>blocks_sub_xx</key>
+ <key>blocks_multiply_const_vxx</key>
<param>
<key>id</key>
- <value>blocks_sub_xx_1</value>
+ <value>blocks_multiply_const_vxx_2_0</value>
</param>
<param>
<key>_enabled</key>
@@ -482,19 +365,15 @@
</param>
<param>
<key>type</key>
- <value>short</value>
- </param>
- <param>
- <key>vlen</key>
- <value>1</value>
+ <value>complex</value>
</param>
<param>
- <key>num_inputs</key>
- <value>2</value>
+ <key>const</key>
+ <value>(1-alpha)**0.5</value>
</param>
<param>
- <key>alias</key>
- <value></value>
+ <key>vlen</key>
+ <value>1</value>
</param>
<param>
<key>affinity</key>
@@ -505,12 +384,8 @@
<value>0</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(540, 1141)</value>
+ <value>(721, 1727)</value>
</param>
<param>
<key>_rotation</key>
@@ -518,30 +393,34 @@
</param>
</block>
<block>
- <key>blocks_sub_xx</key>
+ <key>digital_chunks_to_symbols_xx</key>
<param>
<key>id</key>
- <value>blocks_sub_xx_2_0</value>
+ <value>digital_chunks_to_symbols_xx_0_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
+ <key>in_type</key>
+ <value>byte</value>
+ </param>
+ <param>
+ <key>out_type</key>
<value>complex</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>symbol_table</key>
+ <value>1,1j,-1j,-1</value>
</param>
<param>
- <key>num_inputs</key>
- <value>2</value>
+ <key>dimension</key>
+ <value>1</value>
</param>
<param>
- <key>alias</key>
- <value></value>
+ <key>num_ports</key>
+ <value>1</value>
</param>
<param>
<key>affinity</key>
@@ -552,12 +431,8 @@
<value>0</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(975, 1342)</value>
+ <value>(416, 1251)</value>
</param>
<param>
<key>_rotation</key>
@@ -565,46 +440,22 @@
</param>
</block>
<block>
- <key>blocks_sub_xx</key>
+ <key>virtual_source</key>
<param>
<key>id</key>
- <value>blocks_sub_xx_1_0</value>
+ <value>virtual_source_0_4</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>short</value>
- </param>
- <param>
- <key>vlen</key>
- <value>1</value>
- </param>
- <param>
- <key>num_inputs</key>
- <value>2</value>
- </param>
- <param>
- <key>alias</key>
- <value></value>
- </param>
- <param>
- <key>affinity</key>
- <value></value>
- </param>
- <param>
- <key>minoutbuf</key>
- <value>0</value>
- </param>
- <param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>stream_id</key>
+ <value>user2</value>
</param>
<param>
<key>_coordinate</key>
- <value>(559, 1536)</value>
+ <value>(359, 1373)</value>
</param>
<param>
<key>_rotation</key>
@@ -612,46 +463,22 @@
</param>
</block>
<block>
- <key>blocks_add_xx</key>
+ <key>virtual_source</key>
<param>
<key>id</key>
- <value>blocks_add_xx_0</value>
+ <value>virtual_source_0_2</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>complex</value>
- </param>
- <param>
- <key>num_inputs</key>
- <value>2</value>
- </param>
- <param>
- <key>vlen</key>
- <value>1</value>
- </param>
- <param>
- <key>alias</key>
- <value></value>
- </param>
- <param>
- <key>affinity</key>
- <value></value>
- </param>
- <param>
- <key>minoutbuf</key>
- <value>0</value>
- </param>
- <param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>stream_id</key>
+ <value>user1_est</value>
</param>
<param>
<key>_coordinate</key>
- <value>(1224, 245)</value>
+ <value>(33, 1187)</value>
</param>
<param>
<key>_rotation</key>
@@ -659,10 +486,10 @@
</param>
</block>
<block>
- <key>analog_noise_source_x</key>
+ <key>blocks_sub_xx</key>
<param>
<key>id</key>
- <value>analog_noise_source_x_0</value>
+ <value>blocks_sub_xx_2</value>
</param>
<param>
<key>_enabled</key>
@@ -673,20 +500,12 @@
<value>complex</value>
</param>
<param>
- <key>noise_type</key>
- <value>analog.GR_GAUSSIAN</value>
- </param>
- <param>
- <key>amp</key>
- <value>noisevar</value>
- </param>
- <param>
- <key>seed</key>
- <value>-42</value>
+ <key>vlen</key>
+ <value>1</value>
</param>
<param>
- <key>alias</key>
- <value></value>
+ <key>num_inputs</key>
+ <value>2</value>
</param>
<param>
<key>affinity</key>
@@ -697,12 +516,8 @@
<value>0</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(1178, 321)</value>
+ <value>(942, 1229)</value>
</param>
<param>
<key>_rotation</key>
@@ -710,50 +525,22 @@
</param>
</block>
<block>
- <key>blocks_throttle</key>
+ <key>virtual_source</key>
<param>
<key>id</key>
- <value>blocks_throttle_0</value>
+ <value>virtual_source_0_1_1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>short</value>
- </param>
- <param>
- <key>samples_per_second</key>
- <value>R</value>
- </param>
- <param>
- <key>vlen</key>
- <value>1</value>
- </param>
- <param>
- <key>ignoretag</key>
- <value>True</value>
- </param>
- <param>
- <key>alias</key>
- <value></value>
- </param>
- <param>
- <key>affinity</key>
- <value></value>
- </param>
- <param>
- <key>minoutbuf</key>
- <value>0</value>
- </param>
- <param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>stream_id</key>
+ <value>observation</value>
</param>
<param>
<key>_coordinate</key>
- <value>(579, 143)</value>
+ <value>(698, 1198)</value>
</param>
<param>
<key>_rotation</key>
@@ -764,7 +551,7 @@
<key>blocks_multiply_const_vxx</key>
<param>
<key>id</key>
- <value>blocks_multiply_const_vxx_0</value>
+ <value>blocks_multiply_const_vxx_2</value>
</param>
<param>
<key>_enabled</key>
@@ -783,10 +570,6 @@
<value>1</value>
</param>
<param>
- <key>alias</key>
- <value></value>
- </param>
- <param>
<key>affinity</key>
<value></value>
</param>
@@ -795,12 +578,8 @@
<value>0</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(988, 196)</value>
+ <value>(708, 1259)</value>
</param>
<param>
<key>_rotation</key>
@@ -808,54 +587,45 @@
</param>
</block>
<block>
- <key>digital_chunks_to_symbols_xx</key>
+ <key>virtual_source</key>
<param>
<key>id</key>
- <value>digital_chunks_to_symbols_xx_0</value>
+ <value>virtual_source_0_3</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>in_type</key>
- <value>short</value>
- </param>
- <param>
- <key>out_type</key>
- <value>complex</value>
- </param>
- <param>
- <key>symbol_table</key>
- <value>1,1j,-1j,-1</value>
- </param>
- <param>
- <key>dimension</key>
- <value>1</value>
+ <key>stream_id</key>
+ <value>user2</value>
</param>
<param>
- <key>num_ports</key>
- <value>1</value>
+ <key>_coordinate</key>
+ <value>(342, 928)</value>
</param>
<param>
- <key>alias</key>
- <value></value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_sink</key>
<param>
- <key>affinity</key>
- <value></value>
+ <key>id</key>
+ <value>virtual_sink_0_2_0</value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>stream_id</key>
+ <value>user2_est</value>
</param>
<param>
<key>_coordinate</key>
- <value>(703, 211)</value>
+ <value>(341, 1025)</value>
</param>
<param>
<key>_rotation</key>
@@ -863,46 +633,45 @@
</param>
</block>
<block>
- <key>blocks_multiply_const_vxx</key>
+ <key>virtual_source</key>
<param>
<key>id</key>
- <value>blocks_multiply_const_vxx_1</value>
+ <value>virtual_source_0_1_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>complex</value>
- </param>
- <param>
- <key>const</key>
- <value>(1-alpha)**0.5</value>
+ <key>stream_id</key>
+ <value>observation</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>_coordinate</key>
+ <value>(11, 873)</value>
</param>
<param>
- <key>alias</key>
- <value></value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_source</key>
<param>
- <key>affinity</key>
- <value></value>
+ <key>id</key>
+ <value>virtual_source_0</value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>stream_id</key>
+ <value>user1</value>
</param>
<param>
<key>_coordinate</key>
- <value>(994, 319)</value>
+ <value>(348, 566)</value>
</param>
<param>
<key>_rotation</key>
@@ -910,54 +679,45 @@
</param>
</block>
<block>
- <key>digital_chunks_to_symbols_xx</key>
+ <key>virtual_sink</key>
<param>
<key>id</key>
- <value>digital_chunks_to_symbols_xx_0_0</value>
+ <value>virtual_sink_0_2</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>in_type</key>
- <value>short</value>
- </param>
- <param>
- <key>out_type</key>
- <value>complex</value>
- </param>
- <param>
- <key>symbol_table</key>
- <value>1,1j,-1j,-1</value>
+ <key>stream_id</key>
+ <value>user1_est</value>
</param>
<param>
- <key>dimension</key>
- <value>1</value>
- </param>
- <param>
- <key>num_ports</key>
- <value>1</value>
+ <key>_coordinate</key>
+ <value>(355, 687)</value>
</param>
<param>
- <key>alias</key>
- <value></value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_source</key>
<param>
- <key>affinity</key>
- <value></value>
+ <key>id</key>
+ <value>virtual_source_0_1</value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>stream_id</key>
+ <value>observation</value>
</param>
<param>
<key>_coordinate</key>
- <value>(703, 311)</value>
+ <value>(13, 530)</value>
</param>
<param>
<key>_rotation</key>
@@ -965,84 +725,81 @@
</param>
</block>
<block>
- <key>digital_chunks_to_symbols_xx</key>
+ <key>wxgui_numbersink2</key>
<param>
<key>id</key>
- <value>digital_chunks_to_symbols_xx_0_0_0</value>
+ <value>wxgui_numbersink2_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>in_type</key>
- <value>short</value>
+ <key>type</key>
+ <value>float</value>
</param>
<param>
- <key>out_type</key>
- <value>complex</value>
+ <key>title</key>
+ <value>BER 1 (raw)</value>
</param>
<param>
- <key>symbol_table</key>
- <value>1,1j,-1j,-1</value>
+ <key>units</key>
+ <value>BER</value>
</param>
<param>
- <key>dimension</key>
- <value>1</value>
+ <key>samp_rate</key>
+ <value>R</value>
</param>
<param>
- <key>num_ports</key>
- <value>1</value>
+ <key>min_value</key>
+ <value>0</value>
</param>
<param>
- <key>alias</key>
- <value></value>
+ <key>max_value</key>
+ <value>1</value>
</param>
<param>
- <key>affinity</key>
- <value></value>
+ <key>factor</key>
+ <value>1.0</value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
+ <key>decimal_places</key>
+ <value>6</value>
</param>
<param>
- <key>maxoutbuf</key>
+ <key>ref_level</key>
<value>0</value>
</param>
<param>
- <key>_coordinate</key>
- <value>(418, 1000)</value>
+ <key>number_rate</key>
+ <value>15</value>
</param>
<param>
- <key>_rotation</key>
- <value>0</value>
+ <key>peak_hold</key>
+ <value>False</value>
</param>
- </block>
- <block>
- <key>blocks_multiply_const_vxx</key>
<param>
- <key>id</key>
- <value>blocks_multiply_const_vxx_2</value>
+ <key>average</key>
+ <value>False</value>
</param>
<param>
- <key>_enabled</key>
- <value>True</value>
+ <key>avg_alpha</key>
+ <value>0.001</value>
</param>
<param>
- <key>type</key>
- <value>complex</value>
+ <key>show_gauge</key>
+ <value>True</value>
</param>
<param>
- <key>const</key>
- <value>alpha**0.5</value>
+ <key>win_size</key>
+ <value></value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>grid_pos</key>
+ <value>0,0,1,1</value>
</param>
<param>
- <key>alias</key>
+ <key>notebook</key>
<value></value>
</param>
<param>
@@ -1050,16 +807,8 @@
<value></value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
- </param>
- <param>
- <key>maxoutbuf</key>
- <value>0</value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(710, 1008)</value>
+ <value>(944, 556)</value>
</param>
<param>
<key>_rotation</key>
@@ -1067,10 +816,10 @@
</param>
</block>
<block>
- <key>blocks_multiply_const_vxx</key>
+ <key>wxgui_numbersink2</key>
<param>
<key>id</key>
- <value>blocks_multiply_const_vxx_2_0</value>
+ <value>wxgui_numbersink2_2</value>
</param>
<param>
<key>_enabled</key>
@@ -1078,73 +827,70 @@
</param>
<param>
<key>type</key>
- <value>complex</value>
+ <value>float</value>
</param>
<param>
- <key>const</key>
- <value>(1-alpha)**0.5</value>
+ <key>title</key>
+ <value>BER 2 (raw)</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>units</key>
+ <value>BER</value>
</param>
<param>
- <key>alias</key>
- <value></value>
+ <key>samp_rate</key>
+ <value>R</value>
</param>
<param>
- <key>affinity</key>
- <value></value>
+ <key>min_value</key>
+ <value>0</value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
+ <key>max_value</key>
+ <value>1.0</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>factor</key>
+ <value>1.0</value>
</param>
<param>
- <key>_coordinate</key>
- <value>(733, 1374)</value>
+ <key>decimal_places</key>
+ <value>6</value>
</param>
<param>
- <key>_rotation</key>
+ <key>ref_level</key>
<value>0</value>
</param>
- </block>
- <block>
- <key>digital_chunks_to_symbols_xx</key>
<param>
- <key>id</key>
- <value>digital_chunks_to_symbols_xx_0_0_1</value>
+ <key>number_rate</key>
+ <value>15</value>
</param>
<param>
- <key>_enabled</key>
- <value>True</value>
+ <key>peak_hold</key>
+ <value>False</value>
</param>
<param>
- <key>in_type</key>
- <value>short</value>
+ <key>average</key>
+ <value>False</value>
</param>
<param>
- <key>out_type</key>
- <value>complex</value>
+ <key>avg_alpha</key>
+ <value>0.001</value>
</param>
<param>
- <key>symbol_table</key>
- <value>1,1j,-1j,-1</value>
+ <key>show_gauge</key>
+ <value>True</value>
</param>
<param>
- <key>dimension</key>
- <value>1</value>
+ <key>win_size</key>
+ <value></value>
</param>
<param>
- <key>num_ports</key>
- <value>1</value>
+ <key>grid_pos</key>
+ <value>0,1,1,1</value>
</param>
<param>
- <key>alias</key>
+ <key>notebook</key>
<value></value>
</param>
<param>
@@ -1152,16 +898,8 @@
<value></value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
- </param>
- <param>
- <key>maxoutbuf</key>
- <value>0</value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(420, 1366)</value>
+ <value>(944, 886)</value>
</param>
<param>
<key>_rotation</key>
@@ -1169,128 +907,101 @@
</param>
</block>
<block>
- <key>variable_qtgui_range</key>
+ <key>wxgui_numbersink2</key>
<param>
<key>id</key>
- <value>alpha</value>
+ <value>wxgui_numbersink2_3</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>label</key>
- <value>P1/P</value>
+ <key>type</key>
+ <value>float</value>
</param>
<param>
- <key>value</key>
- <value>0.6</value>
+ <key>title</key>
+ <value>BER 2 (after cancelling user 1)</value>
</param>
<param>
- <key>start</key>
- <value>0</value>
+ <key>units</key>
+ <value>BER</value>
</param>
<param>
- <key>stop</key>
- <value>1</value>
+ <key>samp_rate</key>
+ <value>R</value>
</param>
<param>
- <key>step</key>
- <value>0.01</value>
+ <key>min_value</key>
+ <value>0</value>
</param>
<param>
- <key>widget</key>
- <value>counter_slider</value>
+ <key>max_value</key>
+ <value>1.0</value>
</param>
<param>
- <key>orient</key>
- <value>Qt.Horizontal</value>
+ <key>factor</key>
+ <value>1.0</value>
</param>
<param>
- <key>min_len</key>
- <value>200</value>
+ <key>decimal_places</key>
+ <value>6</value>
</param>
<param>
- <key>gui_hint</key>
- <value></value>
+ <key>ref_level</key>
+ <value>0</value>
</param>
<param>
- <key>alias</key>
- <value></value>
+ <key>number_rate</key>
+ <value>15</value>
</param>
<param>
- <key>_coordinate</key>
- <value>(177, 10)</value>
+ <key>peak_hold</key>
+ <value>False</value>
</param>
<param>
- <key>_rotation</key>
- <value>180</value>
+ <key>average</key>
+ <value>False</value>
</param>
- </block>
- <block>
- <key>variable_qtgui_range</key>
<param>
- <key>id</key>
- <value>snr_db</value>
+ <key>avg_alpha</key>
+ <value>0.001</value>
</param>
<param>
- <key>_enabled</key>
+ <key>show_gauge</key>
<value>True</value>
</param>
<param>
- <key>label</key>
- <value>P/sigma^2 (dB)</value>
- </param>
- <param>
- <key>value</key>
- <value>16</value>
- </param>
- <param>
- <key>start</key>
- <value>0</value>
- </param>
- <param>
- <key>stop</key>
- <value>20</value>
- </param>
- <param>
- <key>step</key>
- <value>0.01</value>
- </param>
- <param>
- <key>widget</key>
- <value>counter_slider</value>
- </param>
- <param>
- <key>orient</key>
- <value>Qt.Horizontal</value>
+ <key>win_size</key>
+ <value></value>
</param>
<param>
- <key>min_len</key>
- <value>200</value>
+ <key>grid_pos</key>
+ <value>1,1,1,1</value>
</param>
<param>
- <key>gui_hint</key>
+ <key>notebook</key>
<value></value>
</param>
<param>
- <key>alias</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(300, 10)</value>
+ <value>(945, 1351)</value>
</param>
<param>
<key>_rotation</key>
- <value>180</value>
+ <value>0</value>
</param>
</block>
<block>
- <key>blocks_add_xx</key>
+ <key>blocks_multiply_const_vxx</key>
<param>
<key>id</key>
- <value>blocks_add_xx_1</value>
+ <value>blocks_multiply_const_vxx_1</value>
</param>
<param>
<key>_enabled</key>
@@ -1301,18 +1012,14 @@
<value>complex</value>
</param>
<param>
- <key>num_inputs</key>
- <value>2</value>
+ <key>const</key>
+ <value>(1-alpha)**0.5</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
- <key>alias</key>
- <value></value>
- </param>
- <param>
<key>affinity</key>
<value></value>
</param>
@@ -1321,12 +1028,8 @@
<value>0</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(1400, 262)</value>
+ <value>(943, 402)</value>
</param>
<param>
<key>_rotation</key>
@@ -1334,10 +1037,10 @@
</param>
</block>
<block>
- <key>qtgui_const_sink_x</key>
+ <key>blocks_multiply_const_vxx</key>
<param>
<key>id</key>
- <value>qtgui_const_sink_x_0</value>
+ <value>blocks_multiply_const_vxx_0</value>
</param>
<param>
<key>_enabled</key>
@@ -1348,320 +1051,141 @@
<value>complex</value>
</param>
<param>
- <key>name</key>
- <value>Constellation</value>
- </param>
- <param>
- <key>size</key>
- <value>1024</value>
- </param>
- <param>
- <key>grid</key>
- <value>False</value>
- </param>
- <param>
- <key>autoscale</key>
- <value>False</value>
- </param>
- <param>
- <key>ymin</key>
- <value>-2</value>
- </param>
- <param>
- <key>ymax</key>
- <value>2</value>
- </param>
- <param>
- <key>xmin</key>
- <value>-2</value>
- </param>
- <param>
- <key>xmax</key>
- <value>2</value>
+ <key>const</key>
+ <value>alpha**0.5</value>
</param>
<param>
- <key>nconnections</key>
+ <key>vlen</key>
<value>1</value>
</param>
<param>
- <key>update_time</key>
- <value>0.10</value>
- </param>
- <param>
- <key>gui_hint</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>tr_mode</key>
- <value>qtgui.TRIG_MODE_FREE</value>
- </param>
- <param>
- <key>tr_slope</key>
- <value>qtgui.TRIG_SLOPE_POS</value>
- </param>
- <param>
- <key>tr_level</key>
- <value>0.0</value>
- </param>
- <param>
- <key>tr_chan</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>tr_tag</key>
- <value>""</value>
- </param>
- <param>
- <key>label1</key>
- <value></value>
- </param>
- <param>
- <key>width1</key>
- <value>1</value>
- </param>
- <param>
- <key>color1</key>
- <value>"blue"</value>
- </param>
- <param>
- <key>style1</key>
- <value>0</value>
+ <key>_coordinate</key>
+ <value>(947, 301)</value>
</param>
<param>
- <key>marker1</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_sink</key>
<param>
- <key>alpha1</key>
- <value>1.0</value>
- </param>
- <param>
- <key>label2</key>
- <value></value>
+ <key>id</key>
+ <value>virtual_sink_0_0</value>
</param>
<param>
- <key>width2</key>
- <value>1</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>color2</key>
- <value>"red"</value>
+ <key>stream_id</key>
+ <value>user2</value>
</param>
<param>
- <key>style2</key>
- <value>0</value>
+ <key>_coordinate</key>
+ <value>(208, 340)</value>
</param>
<param>
- <key>marker2</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>analog_random_source_x</key>
<param>
- <key>alpha2</key>
- <value>1.0</value>
- </param>
- <param>
- <key>label3</key>
- <value></value>
- </param>
- <param>
- <key>width3</key>
- <value>1</value>
+ <key>id</key>
+ <value>analog_random_source_x_1</value>
</param>
<param>
- <key>color3</key>
- <value>"red"</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>style3</key>
- <value>0</value>
+ <key>type</key>
+ <value>byte</value>
</param>
<param>
- <key>marker3</key>
+ <key>min</key>
<value>0</value>
</param>
<param>
- <key>alpha3</key>
- <value>1.0</value>
- </param>
- <param>
- <key>label4</key>
- <value></value>
- </param>
- <param>
- <key>width4</key>
- <value>1</value>
- </param>
- <param>
- <key>color4</key>
- <value>"red"</value>
- </param>
- <param>
- <key>style4</key>
- <value>0</value>
+ <key>max</key>
+ <value>2</value>
</param>
<param>
- <key>marker4</key>
- <value>0</value>
+ <key>num_samps</key>
+ <value>block</value>
</param>
<param>
- <key>alpha4</key>
- <value>1.0</value>
+ <key>repeat</key>
+ <value>True</value>
</param>
<param>
- <key>label5</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>width5</key>
- <value>1</value>
- </param>
- <param>
- <key>color5</key>
- <value>"red"</value>
- </param>
- <param>
- <key>style5</key>
- <value>0</value>
- </param>
- <param>
- <key>marker5</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>alpha5</key>
- <value>1.0</value>
- </param>
- <param>
- <key>label6</key>
- <value></value>
- </param>
- <param>
- <key>width6</key>
- <value>1</value>
- </param>
- <param>
- <key>color6</key>
- <value>"red"</value>
- </param>
- <param>
- <key>style6</key>
- <value>0</value>
+ <key>_coordinate</key>
+ <value>(22, 374)</value>
</param>
<param>
- <key>marker6</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>digital_chunks_to_symbols_xx</key>
<param>
- <key>alpha6</key>
- <value>1.0</value>
- </param>
- <param>
- <key>label7</key>
- <value></value>
- </param>
- <param>
- <key>width7</key>
- <value>1</value>
- </param>
- <param>
- <key>color7</key>
- <value>"red"</value>
+ <key>id</key>
+ <value>digital_chunks_to_symbols_xx_0</value>
</param>
<param>
- <key>style7</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>marker7</key>
- <value>0</value>
+ <key>in_type</key>
+ <value>byte</value>
</param>
<param>
- <key>alpha7</key>
- <value>1.0</value>
+ <key>out_type</key>
+ <value>complex</value>
</param>
<param>
- <key>label8</key>
- <value></value>
+ <key>symbol_table</key>
+ <value>1,1j,-1j,-1</value>
</param>
<param>
- <key>width8</key>
+ <key>dimension</key>
<value>1</value>
</param>
<param>
- <key>color8</key>
- <value>"red"</value>
- </param>
- <param>
- <key>style8</key>
- <value>0</value>
- </param>
- <param>
- <key>marker8</key>
- <value>0</value>
- </param>
- <param>
- <key>alpha8</key>
- <value>1.0</value>
- </param>
- <param>
- <key>label9</key>
- <value></value>
- </param>
- <param>
- <key>width9</key>
+ <key>num_ports</key>
<value>1</value>
</param>
<param>
- <key>color9</key>
- <value>"red"</value>
- </param>
- <param>
- <key>style9</key>
- <value>0</value>
- </param>
- <param>
- <key>marker9</key>
- <value>0</value>
- </param>
- <param>
- <key>alpha9</key>
- <value>1.0</value>
- </param>
- <param>
- <key>label10</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>width10</key>
- <value>1</value>
- </param>
- <param>
- <key>color10</key>
- <value>"red"</value>
- </param>
- <param>
- <key>style10</key>
- <value>0</value>
- </param>
- <param>
- <key>marker10</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>alpha10</key>
- <value>1.0</value>
- </param>
- <param>
- <key>alias</key>
- <value></value>
- </param>
- <param>
- <key>affinity</key>
- <value></value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(0, 0)</value>
+ <value>(700, 294)</value>
</param>
<param>
<key>_rotation</key>
@@ -1669,26 +1193,26 @@
</param>
</block>
<block>
- <key>blocks_short_to_float</key>
+ <key>blocks_throttle</key>
<param>
<key>id</key>
- <value>blocks_short_to_float_0</value>
+ <value>blocks_throttle_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>type</key>
+ <value>byte</value>
</param>
<param>
- <key>scale</key>
- <value>1</value>
+ <key>samples_per_second</key>
+ <value>R</value>
</param>
<param>
- <key>alias</key>
- <value></value>
+ <key>vlen</key>
+ <value>1</value>
</param>
<param>
<key>affinity</key>
@@ -1699,12 +1223,8 @@
<value>0</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(1010, 1551)</value>
+ <value>(576, 226)</value>
</param>
<param>
<key>_rotation</key>
@@ -1712,226 +1232,194 @@
</param>
</block>
<block>
- <key>qtgui_number_sink</key>
+ <key>analog_random_source_x</key>
<param>
<key>id</key>
- <value>qtgui_number_sink_0</value>
+ <value>analog_random_source_x_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>name</key>
- <value>""</value>
- </param>
- <param>
<key>type</key>
- <value>float</value>
- </param>
- <param>
- <key>autoscale</key>
- <value>False</value>
- </param>
- <param>
- <key>avg</key>
- <value>0.001</value>
- </param>
- <param>
- <key>graph_type</key>
- <value>qtgui.NUM_GRAPH_HORIZ</value>
- </param>
- <param>
- <key>nconnections</key>
- <value>1</value>
+ <value>byte</value>
</param>
<param>
<key>min</key>
- <value>-1</value>
+ <value>0</value>
</param>
<param>
<key>max</key>
- <value>1</value>
- </param>
- <param>
- <key>update_time</key>
- <value>0.10</value>
+ <value>2</value>
</param>
<param>
- <key>gui_hint</key>
- <value>0,0,1,1</value>
+ <key>num_samps</key>
+ <value>block</value>
</param>
<param>
- <key>label1</key>
- <value></value>
+ <key>repeat</key>
+ <value>True</value>
</param>
<param>
- <key>unit1</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>color1</key>
- <value>("black", "black")</value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>factor1</key>
- <value>1</value>
+ <key>_coordinate</key>
+ <value>(18, 253)</value>
</param>
<param>
- <key>label2</key>
- <value></value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_sink</key>
<param>
- <key>unit2</key>
- <value></value>
+ <key>id</key>
+ <value>virtual_sink_0</value>
</param>
<param>
- <key>color2</key>
- <value>("black", "black")</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>factor2</key>
- <value>1</value>
+ <key>stream_id</key>
+ <value>user1</value>
</param>
<param>
- <key>label3</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(208, 229)</value>
</param>
<param>
- <key>unit3</key>
- <value></value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>digital_chunks_to_symbols_xx</key>
<param>
- <key>color3</key>
- <value>("black", "black")</value>
+ <key>id</key>
+ <value>digital_chunks_to_symbols_xx_0_0</value>
</param>
<param>
- <key>factor3</key>
- <value>1</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>label4</key>
- <value></value>
+ <key>in_type</key>
+ <value>byte</value>
</param>
<param>
- <key>unit4</key>
- <value></value>
+ <key>out_type</key>
+ <value>complex</value>
</param>
<param>
- <key>color4</key>
- <value>("black", "black")</value>
+ <key>symbol_table</key>
+ <value>1,1j,-1j,-1</value>
</param>
<param>
- <key>factor4</key>
+ <key>dimension</key>
<value>1</value>
</param>
<param>
- <key>label5</key>
- <value></value>
- </param>
- <param>
- <key>unit5</key>
- <value></value>
- </param>
- <param>
- <key>color5</key>
- <value>("black", "black")</value>
- </param>
- <param>
- <key>factor5</key>
+ <key>num_ports</key>
<value>1</value>
</param>
<param>
- <key>label6</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>unit6</key>
- <value></value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>color6</key>
- <value>("black", "black")</value>
+ <key>_coordinate</key>
+ <value>(700, 394)</value>
</param>
<param>
- <key>factor6</key>
- <value>1</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>blocks_add_xx</key>
<param>
- <key>label7</key>
- <value></value>
+ <key>id</key>
+ <value>blocks_add_xx_1</value>
</param>
<param>
- <key>unit7</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>color7</key>
- <value>("black", "black")</value>
+ <key>type</key>
+ <value>complex</value>
</param>
<param>
- <key>factor7</key>
- <value>1</value>
+ <key>num_inputs</key>
+ <value>2</value>
</param>
<param>
- <key>label8</key>
- <value></value>
+ <key>vlen</key>
+ <value>1</value>
</param>
<param>
- <key>unit8</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>color8</key>
- <value>("black", "black")</value>
- </param>
- <param>
- <key>factor8</key>
- <value>1</value>
- </param>
- <param>
- <key>label9</key>
- <value></value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>unit9</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(1400, 341)</value>
</param>
<param>
- <key>color9</key>
- <value>("black", "black")</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>blocks_add_xx</key>
<param>
- <key>factor9</key>
- <value>1</value>
+ <key>id</key>
+ <value>blocks_add_xx_0</value>
</param>
<param>
- <key>label10</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>unit10</key>
- <value></value>
+ <key>type</key>
+ <value>complex</value>
</param>
<param>
- <key>color10</key>
- <value>("black", "black")</value>
+ <key>num_inputs</key>
+ <value>2</value>
</param>
<param>
- <key>factor10</key>
+ <key>vlen</key>
<value>1</value>
</param>
<param>
- <key>alias</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>affinity</key>
- <value></value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
<key>_coordinate</key>
- <value>(1257, 471)</value>
+ <value>(1224, 324)</value>
</param>
<param>
<key>_rotation</key>
@@ -1939,10 +1427,10 @@
</param>
</block>
<block>
- <key>trellis_encoder_xx</key>
+ <key>analog_noise_source_x</key>
<param>
<key>id</key>
- <value>trellis_encoder_xx_1</value>
+ <value>analog_noise_source_x_0</value>
</param>
<param>
<key>_enabled</key>
@@ -1950,19 +1438,19 @@
</param>
<param>
<key>type</key>
- <value>ss</value>
+ <value>complex</value>
</param>
<param>
- <key>fsm_args</key>
- <value>prefix+"/awgn1o2_16.fsm"</value>
+ <key>noise_type</key>
+ <value>analog.GR_GAUSSIAN</value>
</param>
<param>
- <key>init_state</key>
- <value>0</value>
+ <key>amp</key>
+ <value>noisevar</value>
</param>
<param>
- <key>alias</key>
- <value></value>
+ <key>seed</key>
+ <value>-42</value>
</param>
<param>
<key>affinity</key>
@@ -1973,12 +1461,8 @@
<value>0</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(336, 311)</value>
+ <value>(1178, 400)</value>
</param>
<param>
<key>_rotation</key>
@@ -1986,46 +1470,22 @@
</param>
</block>
<block>
- <key>trellis_encoder_xx</key>
+ <key>virtual_sink</key>
<param>
<key>id</key>
- <value>trellis_encoder_xx_0</value>
+ <value>virtual_sink_0_1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>ss</value>
- </param>
- <param>
- <key>fsm_args</key>
- <value>prefix+"/awgn1o2_16.fsm"</value>
- </param>
- <param>
- <key>init_state</key>
- <value>0</value>
- </param>
- <param>
- <key>alias</key>
- <value></value>
- </param>
- <param>
- <key>affinity</key>
- <value></value>
- </param>
- <param>
- <key>minoutbuf</key>
- <value>0</value>
- </param>
- <param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>stream_id</key>
+ <value>observation</value>
</param>
<param>
<key>_coordinate</key>
- <value>(340, 187)</value>
+ <value>(1407, 453)</value>
</param>
<param>
<key>_rotation</key>
@@ -2033,10 +1493,10 @@
</param>
</block>
<block>
- <key>trellis_viterbi_combined_xx</key>
+ <key>wxgui_scopesink2</key>
<param>
<key>id</key>
- <value>trellis_viterbi_combined_xx_1</value>
+ <value>wxgui_scopesink2_0</value>
</param>
<param>
<key>_enabled</key>
@@ -2044,59 +1504,67 @@
</param>
<param>
<key>type</key>
- <value>c</value>
+ <value>complex</value>
</param>
<param>
- <key>out_type</key>
- <value>s</value>
+ <key>title</key>
+ <value>Scope Plot</value>
</param>
<param>
- <key>fsm_args</key>
- <value>prefix+"/awgn1o2_16.fsm"</value>
+ <key>samp_rate</key>
+ <value>R</value>
</param>
<param>
- <key>block_size</key>
- <value>1000</value>
+ <key>v_scale</key>
+ <value>0</value>
</param>
<param>
- <key>init_state</key>
- <value>-1</value>
+ <key>v_offset</key>
+ <value>0</value>
</param>
<param>
- <key>final_state</key>
- <value>-1</value>
+ <key>t_scale</key>
+ <value>0</value>
</param>
<param>
- <key>dim</key>
- <value>1</value>
+ <key>ac_couple</key>
+ <value>False</value>
</param>
<param>
- <key>table</key>
- <value>alpha**0.5*1,alpha**0.5*1j,alpha**0.5*(-1j),alpha**0.5*(-1)</value>
+ <key>xy_mode</key>
+ <value>True</value>
</param>
<param>
- <key>metric_type</key>
- <value>digital.TRELLIS_EUCLIDEAN</value>
+ <key>num_inputs</key>
+ <value>1</value>
</param>
<param>
- <key>alias</key>
+ <key>win_size</key>
<value></value>
</param>
<param>
- <key>affinity</key>
+ <key>grid_pos</key>
<value></value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
+ <key>notebook</key>
+ <value></value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>trig_mode</key>
+ <value>wxgui.TRIG_MODE_AUTO</value>
+ </param>
+ <param>
+ <key>y_axis_label</key>
+ <value>Counts</value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(79, 501)</value>
+ <value>(1383, 208)</value>
</param>
<param>
<key>_rotation</key>
@@ -2107,7 +1575,7 @@
<key>trellis_viterbi_combined_xx</key>
<param>
<key>id</key>
- <value>trellis_viterbi_combined_xx_2</value>
+ <value>trellis_viterbi_combined_xx_1</value>
</param>
<param>
<key>_enabled</key>
@@ -2119,15 +1587,15 @@
</param>
<param>
<key>out_type</key>
- <value>s</value>
+ <value>b</value>
</param>
<param>
<key>fsm_args</key>
- <value>prefix+"/awgn1o2_16.fsm"</value>
+ <value>prefix+fsm1</value>
</param>
<param>
<key>block_size</key>
- <value>1000</value>
+ <value>block</value>
</param>
<param>
<key>init_state</key>
@@ -2143,17 +1611,13 @@
</param>
<param>
<key>table</key>
- <value>(1-alpha)**0.5*1,(1-alpha)**0.5*1j,(1-alpha)**0.5*(-1j),(1-alpha)**0.5*(-1)</value>
+ <value>alpha**0.5*1,alpha**0.5*1j,alpha**0.5*(-1j),alpha**0.5*(-1)</value>
</param>
<param>
<key>metric_type</key>
<value>digital.TRELLIS_EUCLIDEAN</value>
</param>
<param>
- <key>alias</key>
- <value></value>
- </param>
- <param>
<key>affinity</key>
<value></value>
</param>
@@ -2162,12 +1626,8 @@
<value>0</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(82, 766)</value>
+ <value>(75, 583)</value>
</param>
<param>
<key>_rotation</key>
@@ -2178,7 +1638,7 @@
<key>trellis_viterbi_combined_xx</key>
<param>
<key>id</key>
- <value>trellis_viterbi_combined_xx_0</value>
+ <value>trellis_viterbi_combined_xx_0_0</value>
</param>
<param>
<key>_enabled</key>
@@ -2190,15 +1650,15 @@
</param>
<param>
<key>out_type</key>
- <value>s</value>
+ <value>b</value>
</param>
<param>
<key>fsm_args</key>
- <value>prefix+"/awgn1o2_16.fsm"</value>
+ <value>prefix+fsm1</value>
</param>
<param>
<key>block_size</key>
- <value>1000</value>
+ <value>block</value>
</param>
<param>
<key>init_state</key>
@@ -2214,17 +1674,13 @@
</param>
<param>
<key>table</key>
- <value>(1-alpha)**0.5*1,(1-alpha)**0.5*1j,(1-alpha)**0.5*(-1j),(1-alpha)**0.5*(-1)</value>
+ <value>alpha**0.5*1,alpha**0.5*1j,alpha**0.5*(-1j),alpha**0.5*(-1)</value>
</param>
<param>
<key>metric_type</key>
<value>digital.TRELLIS_EUCLIDEAN</value>
</param>
<param>
- <key>alias</key>
- <value></value>
- </param>
- <param>
<key>affinity</key>
<value></value>
</param>
@@ -2233,12 +1689,8 @@
<value>0</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(83, 1111)</value>
+ <value>(63, 1848)</value>
</param>
<param>
<key>_rotation</key>
@@ -2246,10 +1698,10 @@
</param>
</block>
<block>
- <key>trellis_viterbi_combined_xx</key>
+ <key>trellis_encoder_xx</key>
<param>
<key>id</key>
- <value>trellis_viterbi_combined_xx_0_0</value>
+ <value>trellis_encoder_xx_0</value>
</param>
<param>
<key>_enabled</key>
@@ -2257,43 +1709,15 @@
</param>
<param>
<key>type</key>
- <value>c</value>
- </param>
- <param>
- <key>out_type</key>
- <value>s</value>
+ <value>bb</value>
</param>
<param>
<key>fsm_args</key>
- <value>prefix+"/awgn1o2_16.fsm"</value>
- </param>
- <param>
- <key>block_size</key>
- <value>1000</value>
+ <value>prefix+fsm1</value>
</param>
<param>
<key>init_state</key>
- <value>-1</value>
- </param>
- <param>
- <key>final_state</key>
- <value>-1</value>
- </param>
- <param>
- <key>dim</key>
- <value>1</value>
- </param>
- <param>
- <key>table</key>
- <value>alpha**0.5*1,alpha**0.5*1j,alpha**0.5*(-1j),alpha**0.5*(-1)</value>
- </param>
- <param>
- <key>metric_type</key>
- <value>digital.TRELLIS_EUCLIDEAN</value>
- </param>
- <param>
- <key>alias</key>
- <value></value>
+ <value>0</value>
</param>
<param>
<key>affinity</key>
@@ -2304,12 +1728,8 @@
<value>0</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(75, 1495)</value>
+ <value>(337, 270)</value>
</param>
<param>
<key>_rotation</key>
@@ -2317,10 +1737,10 @@
</param>
</block>
<block>
- <key>blocks_multiply_xx</key>
+ <key>trellis_encoder_xx</key>
<param>
<key>id</key>
- <value>blocks_multiply_xx_2_0</value>
+ <value>trellis_encoder_xx_2</value>
</param>
<param>
<key>_enabled</key>
@@ -2328,19 +1748,15 @@
</param>
<param>
<key>type</key>
- <value>short</value>
- </param>
- <param>
- <key>num_inputs</key>
- <value>2</value>
+ <value>bb</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>fsm_args</key>
+ <value>prefix+fsm1</value>
</param>
<param>
- <key>alias</key>
- <value></value>
+ <key>init_state</key>
+ <value>0</value>
</param>
<param>
<key>affinity</key>
@@ -2351,12 +1767,8 @@
<value>0</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(771, 1530)</value>
+ <value>(87, 1251)</value>
</param>
<param>
<key>_rotation</key>
@@ -2364,26 +1776,26 @@
</param>
</block>
<block>
- <key>blocks_short_to_float</key>
+ <key>trellis_encoder_xx</key>
<param>
<key>id</key>
- <value>blocks_short_to_float_1</value>
+ <value>trellis_encoder_xx_1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>type</key>
+ <value>bb</value>
</param>
<param>
- <key>scale</key>
- <value>1</value>
+ <key>fsm_args</key>
+ <value>prefix+fsm2</value>
</param>
<param>
- <key>alias</key>
- <value></value>
+ <key>init_state</key>
+ <value>0</value>
</param>
<param>
<key>affinity</key>
@@ -2394,12 +1806,8 @@
<value>0</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(985, 1608)</value>
+ <value>(376, 381)</value>
</param>
<param>
<key>_rotation</key>
@@ -2407,226 +1815,62 @@
</param>
</block>
<block>
- <key>qtgui_number_sink</key>
+ <key>trellis_viterbi_combined_xx</key>
<param>
<key>id</key>
- <value>qtgui_number_sink_0_0_0_0</value>
+ <value>trellis_viterbi_combined_xx_2</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>name</key>
- <value>""</value>
- </param>
- <param>
<key>type</key>
- <value>float</value>
- </param>
- <param>
- <key>autoscale</key>
- <value>False</value>
+ <value>c</value>
</param>
<param>
- <key>avg</key>
- <value>0.001</value>
+ <key>out_type</key>
+ <value>b</value>
</param>
<param>
- <key>graph_type</key>
- <value>qtgui.NUM_GRAPH_HORIZ</value>
+ <key>fsm_args</key>
+ <value>prefix+fsm2</value>
</param>
<param>
- <key>nconnections</key>
- <value>1</value>
+ <key>block_size</key>
+ <value>block</value>
</param>
<param>
- <key>min</key>
+ <key>init_state</key>
<value>-1</value>
</param>
<param>
- <key>max</key>
- <value>1</value>
- </param>
- <param>
- <key>update_time</key>
- <value>0.10</value>
- </param>
- <param>
- <key>gui_hint</key>
- <value>1,0,1,1</value>
- </param>
- <param>
- <key>label1</key>
- <value>BER 2 (raw)</value>
- </param>
- <param>
- <key>unit1</key>
- <value></value>
- </param>
- <param>
- <key>color1</key>
- <value>("black", "black")</value>
- </param>
- <param>
- <key>factor1</key>
- <value>1</value>
- </param>
- <param>
- <key>label2</key>
- <value></value>
- </param>
- <param>
- <key>unit2</key>
- <value></value>
- </param>
- <param>
- <key>color2</key>
- <value>("black", "black")</value>
- </param>
- <param>
- <key>factor2</key>
- <value>1</value>
- </param>
- <param>
- <key>label3</key>
- <value></value>
- </param>
- <param>
- <key>unit3</key>
- <value></value>
- </param>
- <param>
- <key>color3</key>
- <value>("black", "black")</value>
- </param>
- <param>
- <key>factor3</key>
- <value>1</value>
- </param>
- <param>
- <key>label4</key>
- <value></value>
- </param>
- <param>
- <key>unit4</key>
- <value></value>
- </param>
- <param>
- <key>color4</key>
- <value>("black", "black")</value>
- </param>
- <param>
- <key>factor4</key>
- <value>1</value>
- </param>
- <param>
- <key>label5</key>
- <value></value>
- </param>
- <param>
- <key>unit5</key>
- <value></value>
- </param>
- <param>
- <key>color5</key>
- <value>("black", "black")</value>
- </param>
- <param>
- <key>factor5</key>
- <value>1</value>
- </param>
- <param>
- <key>label6</key>
- <value></value>
- </param>
- <param>
- <key>unit6</key>
- <value></value>
- </param>
- <param>
- <key>color6</key>
- <value>("black", "black")</value>
- </param>
- <param>
- <key>factor6</key>
- <value>1</value>
- </param>
- <param>
- <key>label7</key>
- <value></value>
- </param>
- <param>
- <key>unit7</key>
- <value></value>
- </param>
- <param>
- <key>color7</key>
- <value>("black", "black")</value>
- </param>
- <param>
- <key>factor7</key>
- <value>1</value>
- </param>
- <param>
- <key>label8</key>
- <value></value>
- </param>
- <param>
- <key>unit8</key>
- <value></value>
- </param>
- <param>
- <key>color8</key>
- <value>("black", "black")</value>
- </param>
- <param>
- <key>factor8</key>
- <value>1</value>
- </param>
- <param>
- <key>label9</key>
- <value></value>
- </param>
- <param>
- <key>unit9</key>
- <value></value>
- </param>
- <param>
- <key>color9</key>
- <value>("black", "black")</value>
+ <key>final_state</key>
+ <value>-1</value>
</param>
<param>
- <key>factor9</key>
+ <key>dim</key>
<value>1</value>
</param>
<param>
- <key>label10</key>
- <value></value>
- </param>
- <param>
- <key>unit10</key>
- <value></value>
- </param>
- <param>
- <key>color10</key>
- <value>("black", "black")</value>
+ <key>table</key>
+ <value>(1-alpha)**0.5*1,(1-alpha)**0.5*1j,(1-alpha)**0.5*(-1j),(1-alpha)**0.5*(-1)</value>
</param>
<param>
- <key>factor10</key>
- <value>1</value>
+ <key>metric_type</key>
+ <value>digital.TRELLIS_EUCLIDEAN</value>
</param>
<param>
- <key>alias</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>affinity</key>
- <value></value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
<key>_coordinate</key>
- <value>(1272, 1551)</value>
+ <value>(85, 931)</value>
</param>
<param>
<key>_rotation</key>
@@ -2634,10 +1878,10 @@
</param>
</block>
<block>
- <key>blocks_multiply_xx</key>
+ <key>trellis_viterbi_combined_xx</key>
<param>
<key>id</key>
- <value>blocks_multiply_xx_1</value>
+ <value>trellis_viterbi_combined_xx_0</value>
</param>
<param>
<key>_enabled</key>
@@ -2645,62 +1889,39 @@
</param>
<param>
<key>type</key>
- <value>short</value>
- </param>
- <param>
- <key>num_inputs</key>
- <value>2</value>
- </param>
- <param>
- <key>vlen</key>
- <value>1</value>
- </param>
- <param>
- <key>alias</key>
- <value></value>
- </param>
- <param>
- <key>affinity</key>
- <value></value>
- </param>
- <param>
- <key>minoutbuf</key>
- <value>0</value>
+ <value>c</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>out_type</key>
+ <value>b</value>
</param>
<param>
- <key>_coordinate</key>
- <value>(785, 779)</value>
+ <key>fsm_args</key>
+ <value>prefix+fsm2</value>
</param>
<param>
- <key>_rotation</key>
- <value>0</value>
+ <key>block_size</key>
+ <value>block</value>
</param>
- </block>
- <block>
- <key>blocks_short_to_float</key>
<param>
- <key>id</key>
- <value>blocks_short_to_float_2</value>
+ <key>init_state</key>
+ <value>-1</value>
</param>
<param>
- <key>_enabled</key>
- <value>True</value>
+ <key>final_state</key>
+ <value>-1</value>
</param>
<param>
- <key>vlen</key>
+ <key>dim</key>
<value>1</value>
</param>
<param>
- <key>scale</key>
- <value>1</value>
+ <key>table</key>
+ <value>(1-alpha)**0.5*1,(1-alpha)**0.5*1j,(1-alpha)**0.5*(-1j),(1-alpha)**0.5*(-1)</value>
</param>
<param>
- <key>alias</key>
- <value></value>
+ <key>metric_type</key>
+ <value>digital.TRELLIS_EUCLIDEAN</value>
</param>
<param>
<key>affinity</key>
@@ -2711,12 +1932,8 @@
<value>0</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(1013, 735)</value>
+ <value>(81, 1362)</value>
</param>
<param>
<key>_rotation</key>
@@ -2724,10 +1941,10 @@
</param>
</block>
<block>
- <key>blocks_multiply_xx</key>
+ <key>trellis_encoder_xx</key>
<param>
<key>id</key>
- <value>blocks_multiply_xx_2</value>
+ <value>trellis_encoder_xx_2_0</value>
</param>
<param>
<key>_enabled</key>
@@ -2735,63 +1952,16 @@
</param>
<param>
<key>type</key>
- <value>short</value>
- </param>
- <param>
- <key>num_inputs</key>
- <value>2</value>
- </param>
- <param>
- <key>vlen</key>
- <value>1</value>
- </param>
- <param>
- <key>alias</key>
- <value></value>
- </param>
- <param>
- <key>affinity</key>
- <value></value>
- </param>
- <param>
- <key>minoutbuf</key>
- <value>0</value>
- </param>
- <param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <value>bb</value>
</param>
<param>
- <key>_coordinate</key>
- <value>(796, 1136)</value>
+ <key>fsm_args</key>
+ <value>prefix+fsm2</value>
</param>
<param>
- <key>_rotation</key>
+ <key>init_state</key>
<value>0</value>
</param>
- </block>
- <block>
- <key>blocks_short_to_float</key>
- <param>
- <key>id</key>
- <value>blocks_short_to_float_3</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>vlen</key>
- <value>1</value>
- </param>
- <param>
- <key>scale</key>
- <value>1</value>
- </param>
- <param>
- <key>alias</key>
- <value></value>
- </param>
<param>
<key>affinity</key>
<value></value>
@@ -2801,12 +1971,8 @@
<value>0</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(1002, 1149)</value>
+ <value>(91, 1719)</value>
</param>
<param>
<key>_rotation</key>
@@ -2814,226 +1980,200 @@
</param>
</block>
<block>
- <key>qtgui_number_sink</key>
+ <key>wxgui_numbersink2</key>
<param>
<key>id</key>
- <value>qtgui_number_sink_0_0</value>
+ <value>wxgui_numbersink2_3_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>name</key>
- <value>""</value>
- </param>
- <param>
<key>type</key>
<value>float</value>
</param>
<param>
- <key>autoscale</key>
- <value>False</value>
- </param>
- <param>
- <key>avg</key>
- <value>0.001</value>
- </param>
- <param>
- <key>graph_type</key>
- <value>qtgui.NUM_GRAPH_HORIZ</value>
- </param>
- <param>
- <key>nconnections</key>
- <value>1</value>
- </param>
- <param>
- <key>min</key>
- <value>-1</value>
+ <key>title</key>
+ <value>BER 1 (after cancelling user 2)</value>
</param>
<param>
- <key>max</key>
- <value>1</value>
+ <key>units</key>
+ <value>BER</value>
</param>
<param>
- <key>update_time</key>
- <value>0.10</value>
+ <key>samp_rate</key>
+ <value>R</value>
</param>
<param>
- <key>gui_hint</key>
- <value>0,1,1,1</value>
+ <key>min_value</key>
+ <value>0</value>
</param>
<param>
- <key>label1</key>
- <value>BER 2 (raw)</value>
+ <key>max_value</key>
+ <value>1.0</value>
</param>
<param>
- <key>unit1</key>
- <value></value>
+ <key>factor</key>
+ <value>1.0</value>
</param>
<param>
- <key>color1</key>
- <value>("black", "black")</value>
+ <key>decimal_places</key>
+ <value>6</value>
</param>
<param>
- <key>factor1</key>
- <value>1</value>
+ <key>ref_level</key>
+ <value>0</value>
</param>
<param>
- <key>label2</key>
- <value></value>
+ <key>number_rate</key>
+ <value>15</value>
</param>
<param>
- <key>unit2</key>
- <value></value>
+ <key>peak_hold</key>
+ <value>False</value>
</param>
<param>
- <key>color2</key>
- <value>("black", "black")</value>
+ <key>average</key>
+ <value>False</value>
</param>
<param>
- <key>factor2</key>
- <value>1</value>
+ <key>avg_alpha</key>
+ <value>0.001</value>
</param>
<param>
- <key>label3</key>
- <value></value>
+ <key>show_gauge</key>
+ <value>True</value>
</param>
<param>
- <key>unit3</key>
+ <key>win_size</key>
<value></value>
</param>
<param>
- <key>color3</key>
- <value>("black", "black")</value>
- </param>
- <param>
- <key>factor3</key>
- <value>1</value>
+ <key>grid_pos</key>
+ <value>1,0,1,1</value>
</param>
<param>
- <key>label4</key>
+ <key>notebook</key>
<value></value>
</param>
<param>
- <key>unit4</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>color4</key>
- <value>("black", "black")</value>
+ <key>_coordinate</key>
+ <value>(929, 1816)</value>
</param>
<param>
- <key>factor4</key>
- <value>1</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>variable_slider</key>
<param>
- <key>label5</key>
- <value></value>
+ <key>id</key>
+ <value>alpha</value>
</param>
<param>
- <key>unit5</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>color5</key>
- <value>("black", "black")</value>
+ <key>label</key>
+ <value>P1/P</value>
</param>
<param>
- <key>factor5</key>
- <value>1</value>
+ <key>value</key>
+ <value>0.1</value>
</param>
<param>
- <key>label6</key>
- <value></value>
+ <key>min</key>
+ <value>0</value>
</param>
<param>
- <key>unit6</key>
- <value></value>
+ <key>max</key>
+ <value>1.0</value>
</param>
<param>
- <key>color6</key>
- <value>("black", "black")</value>
+ <key>num_steps</key>
+ <value>100</value>
</param>
<param>
- <key>factor6</key>
- <value>1</value>
+ <key>style</key>
+ <value>wx.SL_HORIZONTAL</value>
</param>
<param>
- <key>label7</key>
- <value></value>
+ <key>converver</key>
+ <value>float_converter</value>
</param>
<param>
- <key>unit7</key>
+ <key>grid_pos</key>
<value></value>
</param>
<param>
- <key>color7</key>
- <value>("black", "black")</value>
- </param>
- <param>
- <key>factor7</key>
- <value>1</value>
- </param>
- <param>
- <key>label8</key>
+ <key>notebook</key>
<value></value>
</param>
<param>
- <key>unit8</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(243, 11)</value>
</param>
<param>
- <key>color8</key>
- <value>("black", "black")</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>variable_slider</key>
<param>
- <key>factor8</key>
- <value>1</value>
+ <key>id</key>
+ <value>snr_db</value>
</param>
<param>
- <key>label9</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>unit9</key>
- <value></value>
+ <key>label</key>
+ <value>P/sigma^2 (dB)</value>
</param>
<param>
- <key>color9</key>
- <value>("black", "black")</value>
+ <key>value</key>
+ <value>10</value>
</param>
<param>
- <key>factor9</key>
- <value>1</value>
+ <key>min</key>
+ <value>0</value>
</param>
<param>
- <key>label10</key>
- <value></value>
+ <key>max</key>
+ <value>20</value>
</param>
<param>
- <key>unit10</key>
- <value></value>
+ <key>num_steps</key>
+ <value>100</value>
</param>
<param>
- <key>color10</key>
- <value>("black", "black")</value>
+ <key>style</key>
+ <value>wx.SL_HORIZONTAL</value>
</param>
<param>
- <key>factor10</key>
- <value>1</value>
+ <key>converver</key>
+ <value>float_converter</value>
</param>
<param>
- <key>alias</key>
+ <key>grid_pos</key>
<value></value>
</param>
<param>
- <key>affinity</key>
+ <key>notebook</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(1223, 1133)</value>
+ <value>(447, 14)</value>
</param>
<param>
<key>_rotation</key>
@@ -3041,10 +2181,10 @@
</param>
</block>
<block>
- <key>trellis_encoder_xx</key>
+ <key>blks2_error_rate</key>
<param>
<key>id</key>
- <value>trellis_encoder_xx_2_0</value>
+ <value>blks2_error_rate_0</value>
</param>
<param>
<key>_enabled</key>
@@ -3052,19 +2192,15 @@
</param>
<param>
<key>type</key>
- <value>ss</value>
+ <value>'BER'</value>
</param>
<param>
- <key>fsm_args</key>
- <value>prefix+"/awgn1o2_16.fsm"</value>
+ <key>win_size</key>
+ <value>block*100</value>
</param>
<param>
- <key>init_state</key>
- <value>0</value>
- </param>
- <param>
- <key>alias</key>
- <value></value>
+ <key>bits_per_symbol</key>
+ <value>2</value>
</param>
<param>
<key>affinity</key>
@@ -3075,12 +2211,8 @@
<value>0</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(103, 1366)</value>
+ <value>(724, 613)</value>
</param>
<param>
<key>_rotation</key>
@@ -3088,10 +2220,10 @@
</param>
</block>
<block>
- <key>trellis_encoder_xx</key>
+ <key>blks2_error_rate</key>
<param>
<key>id</key>
- <value>trellis_encoder_xx_2</value>
+ <value>blks2_error_rate_0_0</value>
</param>
<param>
<key>_enabled</key>
@@ -3099,19 +2231,15 @@
</param>
<param>
<key>type</key>
- <value>ss</value>
+ <value>'BER'</value>
</param>
<param>
- <key>fsm_args</key>
- <value>prefix+"/awgn1o2_16.fsm"</value>
- </param>
- <param>
- <key>init_state</key>
- <value>0</value>
+ <key>win_size</key>
+ <value>block*100</value>
</param>
<param>
- <key>alias</key>
- <value></value>
+ <key>bits_per_symbol</key>
+ <value>2</value>
</param>
<param>
<key>affinity</key>
@@ -3122,12 +2250,8 @@
<value>0</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(89, 1000)</value>
+ <value>(719, 943)</value>
</param>
<param>
<key>_rotation</key>
@@ -3135,226 +2259,77 @@
</param>
</block>
<block>
- <key>qtgui_number_sink</key>
+ <key>blks2_error_rate</key>
<param>
<key>id</key>
- <value>qtgui_number_sink_0_0_0</value>
+ <value>blks2_error_rate_0_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>name</key>
- <value>""</value>
- </param>
- <param>
<key>type</key>
- <value>float</value>
- </param>
- <param>
- <key>autoscale</key>
- <value>False</value>
- </param>
- <param>
- <key>avg</key>
- <value>0.001</value>
- </param>
- <param>
- <key>graph_type</key>
- <value>qtgui.NUM_GRAPH_HORIZ</value>
- </param>
- <param>
- <key>nconnections</key>
- <value>1</value>
- </param>
- <param>
- <key>min</key>
- <value>-1</value>
- </param>
- <param>
- <key>max</key>
- <value>1</value>
- </param>
- <param>
- <key>update_time</key>
- <value>0.10</value>
- </param>
- <param>
- <key>gui_hint</key>
- <value>1,1,1,1</value>
- </param>
- <param>
- <key>label1</key>
- <value></value>
- </param>
- <param>
- <key>unit1</key>
- <value></value>
- </param>
- <param>
- <key>color1</key>
- <value>("black", "black")</value>
- </param>
- <param>
- <key>factor1</key>
- <value>1</value>
- </param>
- <param>
- <key>label2</key>
- <value></value>
- </param>
- <param>
- <key>unit2</key>
- <value></value>
- </param>
- <param>
- <key>color2</key>
- <value>("black", "black")</value>
- </param>
- <param>
- <key>factor2</key>
- <value>1</value>
- </param>
- <param>
- <key>label3</key>
- <value></value>
- </param>
- <param>
- <key>unit3</key>
- <value></value>
- </param>
- <param>
- <key>color3</key>
- <value>("black", "black")</value>
- </param>
- <param>
- <key>factor3</key>
- <value>1</value>
- </param>
- <param>
- <key>label4</key>
- <value></value>
- </param>
- <param>
- <key>unit4</key>
- <value></value>
- </param>
- <param>
- <key>color4</key>
- <value>("black", "black")</value>
+ <value>'BER'</value>
</param>
<param>
- <key>factor4</key>
- <value>1</value>
- </param>
- <param>
- <key>label5</key>
- <value></value>
- </param>
- <param>
- <key>unit5</key>
- <value></value>
- </param>
- <param>
- <key>color5</key>
- <value>("black", "black")</value>
- </param>
- <param>
- <key>factor5</key>
- <value>1</value>
- </param>
- <param>
- <key>label6</key>
- <value></value>
- </param>
- <param>
- <key>unit6</key>
- <value></value>
- </param>
- <param>
- <key>color6</key>
- <value>("black", "black")</value>
- </param>
- <param>
- <key>factor6</key>
- <value>1</value>
- </param>
- <param>
- <key>label7</key>
- <value></value>
- </param>
- <param>
- <key>unit7</key>
- <value></value>
- </param>
- <param>
- <key>color7</key>
- <value>("black", "black")</value>
- </param>
- <param>
- <key>factor7</key>
- <value>1</value>
+ <key>win_size</key>
+ <value>block*100</value>
</param>
<param>
- <key>label8</key>
- <value></value>
+ <key>bits_per_symbol</key>
+ <value>2</value>
</param>
<param>
- <key>unit8</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>color8</key>
- <value>("black", "black")</value>
- </param>
- <param>
- <key>factor8</key>
- <value>1</value>
- </param>
- <param>
- <key>label9</key>
- <value></value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>unit9</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(725, 1399)</value>
</param>
<param>
- <key>color9</key>
- <value>("black", "black")</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>blks2_error_rate</key>
<param>
- <key>factor9</key>
- <value>1</value>
+ <key>id</key>
+ <value>blks2_error_rate_0_0_0_0</value>
</param>
<param>
- <key>label10</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>unit10</key>
- <value></value>
+ <key>type</key>
+ <value>'BER'</value>
</param>
<param>
- <key>color10</key>
- <value>("black", "black")</value>
+ <key>win_size</key>
+ <value>block*100</value>
</param>
<param>
- <key>factor10</key>
- <value>1</value>
+ <key>bits_per_symbol</key>
+ <value>2</value>
</param>
<param>
- <key>alias</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>affinity</key>
- <value></value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
<key>_coordinate</key>
- <value>(1266, 720)</value>
+ <value>(724, 1880)</value>
</param>
<param>
<key>_rotation</key>
@@ -3362,218 +2337,194 @@
</param>
</block>
<connection>
- <source_block_id>analog_random_source_x_1</source_block_id>
- <sink_block_id>trellis_encoder_xx_1</sink_block_id>
- <source_key>0</source_key>
- <sink_key>0</sink_key>
- </connection>
- <connection>
- <source_block_id>blocks_multiply_const_vxx_0</source_block_id>
- <sink_block_id>blocks_add_xx_0</sink_block_id>
+ <source_block_id>blocks_add_xx_1</source_block_id>
+ <sink_block_id>wxgui_scopesink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_add_xx_0</source_block_id>
- <sink_block_id>blocks_add_xx_1</sink_block_id>
+ <source_block_id>blocks_add_xx_1</source_block_id>
+ <sink_block_id>virtual_sink_0_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_multiply_const_vxx_1</source_block_id>
- <sink_block_id>blocks_add_xx_0</sink_block_id>
+ <source_block_id>trellis_viterbi_combined_xx_0_0</source_block_id>
+ <sink_block_id>blks2_error_rate_0_0_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>1</sink_key>
</connection>
<connection>
- <source_block_id>blocks_sub_xx_0</source_block_id>
- <sink_block_id>blocks_multiply_xx_0</sink_block_id>
+ <source_block_id>virtual_source_0_0</source_block_id>
+ <sink_block_id>blks2_error_rate_0_0_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_sub_xx_0</source_block_id>
- <sink_block_id>blocks_multiply_xx_0</sink_block_id>
+ <source_block_id>blks2_error_rate_0_0_0_0</source_block_id>
+ <sink_block_id>wxgui_numbersink2_3_0</sink_block_id>
<source_key>0</source_key>
- <sink_key>1</sink_key>
+ <sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_multiply_xx_0</source_block_id>
- <sink_block_id>blocks_short_to_float_0</sink_block_id>
+ <source_block_id>virtual_source_0_2_0</source_block_id>
+ <sink_block_id>trellis_encoder_xx_2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>analog_random_source_x_0</source_block_id>
- <sink_block_id>trellis_encoder_xx_0</sink_block_id>
+ <source_block_id>virtual_source_0_1_2</source_block_id>
+ <sink_block_id>blocks_sub_xx_2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_add_xx_1</source_block_id>
- <sink_block_id>trellis_viterbi_combined_xx_1</sink_block_id>
+ <source_block_id>digital_chunks_to_symbols_xx_0_0_1</source_block_id>
+ <sink_block_id>blocks_multiply_const_vxx_2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>analog_random_source_x_0</source_block_id>
- <sink_block_id>blocks_sub_xx_0</sink_block_id>
+ <source_block_id>trellis_encoder_xx_2_0</source_block_id>
+ <sink_block_id>digital_chunks_to_symbols_xx_0_0_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>trellis_viterbi_combined_xx_1</source_block_id>
- <sink_block_id>blocks_sub_xx_0</sink_block_id>
+ <source_block_id>blocks_multiply_const_vxx_2_0</source_block_id>
+ <sink_block_id>blocks_sub_xx_2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>1</sink_key>
</connection>
<connection>
- <source_block_id>trellis_viterbi_combined_xx_0</source_block_id>
- <sink_block_id>blocks_sub_xx_1</sink_block_id>
+ <source_block_id>blocks_sub_xx_2_0</source_block_id>
+ <sink_block_id>trellis_viterbi_combined_xx_0_0</sink_block_id>
<source_key>0</source_key>
- <sink_key>1</sink_key>
+ <sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>analog_random_source_x_1</source_block_id>
- <sink_block_id>blocks_sub_xx_1</sink_block_id>
+ <source_block_id>trellis_viterbi_combined_xx_0</source_block_id>
+ <sink_block_id>blks2_error_rate_0_0_0</sink_block_id>
<source_key>0</source_key>
- <sink_key>0</sink_key>
+ <sink_key>1</sink_key>
</connection>
<connection>
- <source_block_id>blocks_sub_xx_1</source_block_id>
- <sink_block_id>blocks_multiply_xx_2</sink_block_id>
+ <source_block_id>virtual_source_0_4</source_block_id>
+ <sink_block_id>blks2_error_rate_0_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_sub_xx_1</source_block_id>
- <sink_block_id>blocks_multiply_xx_2</sink_block_id>
+ <source_block_id>blks2_error_rate_0_0_0</source_block_id>
+ <sink_block_id>wxgui_numbersink2_3</sink_block_id>
<source_key>0</source_key>
- <sink_key>1</sink_key>
+ <sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_sub_xx_2</source_block_id>
- <sink_block_id>trellis_viterbi_combined_xx_0</sink_block_id>
+ <source_block_id>virtual_source_0_2</source_block_id>
+ <sink_block_id>trellis_encoder_xx_2</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_add_xx_1</source_block_id>
+ <source_block_id>virtual_source_0_1_1</source_block_id>
<sink_block_id>blocks_sub_xx_2</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_multiply_const_vxx_2</source_block_id>
- <sink_block_id>blocks_sub_xx_2</sink_block_id>
+ <source_block_id>digital_chunks_to_symbols_xx_0_0_0</source_block_id>
+ <sink_block_id>blocks_multiply_const_vxx_2</sink_block_id>
<source_key>0</source_key>
- <sink_key>1</sink_key>
+ <sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>trellis_viterbi_combined_xx_1</source_block_id>
- <sink_block_id>trellis_encoder_xx_2</sink_block_id>
+ <source_block_id>trellis_encoder_xx_2</source_block_id>
+ <sink_block_id>digital_chunks_to_symbols_xx_0_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>trellis_viterbi_combined_xx_2</source_block_id>
- <sink_block_id>blocks_sub_xx_3</sink_block_id>
+ <source_block_id>blocks_multiply_const_vxx_2</source_block_id>
+ <sink_block_id>blocks_sub_xx_2</sink_block_id>
<source_key>0</source_key>
<sink_key>1</sink_key>
</connection>
<connection>
- <source_block_id>blocks_sub_xx_3</source_block_id>
- <sink_block_id>blocks_multiply_xx_1</sink_block_id>
+ <source_block_id>blocks_sub_xx_2</source_block_id>
+ <sink_block_id>trellis_viterbi_combined_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_sub_xx_3</source_block_id>
- <sink_block_id>blocks_multiply_xx_1</sink_block_id>
- <source_key>0</source_key>
- <sink_key>1</sink_key>
- </connection>
- <connection>
- <source_block_id>analog_random_source_x_1</source_block_id>
- <sink_block_id>blocks_sub_xx_3</sink_block_id>
+ <source_block_id>blks2_error_rate_0_0</source_block_id>
+ <sink_block_id>wxgui_numbersink2_2</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>trellis_viterbi_combined_xx_2</source_block_id>
- <sink_block_id>trellis_encoder_xx_2_0</sink_block_id>
+ <source_block_id>virtual_source_0_3</source_block_id>
+ <sink_block_id>blks2_error_rate_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>trellis_viterbi_combined_xx_0_0</source_block_id>
- <sink_block_id>blocks_sub_xx_1_0</sink_block_id>
+ <source_block_id>trellis_viterbi_combined_xx_2</source_block_id>
+ <sink_block_id>blks2_error_rate_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>1</sink_key>
</connection>
<connection>
- <source_block_id>blocks_sub_xx_1_0</source_block_id>
- <sink_block_id>blocks_multiply_xx_2_0</sink_block_id>
+ <source_block_id>trellis_viterbi_combined_xx_2</source_block_id>
+ <sink_block_id>virtual_sink_0_2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_sub_xx_1_0</source_block_id>
- <sink_block_id>blocks_multiply_xx_2_0</sink_block_id>
- <source_key>0</source_key>
- <sink_key>1</sink_key>
- </connection>
- <connection>
- <source_block_id>blocks_sub_xx_2_0</source_block_id>
- <sink_block_id>trellis_viterbi_combined_xx_0_0</sink_block_id>
+ <source_block_id>virtual_source_0_1_0</source_block_id>
+ <sink_block_id>trellis_viterbi_combined_xx_2</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_add_xx_1</source_block_id>
- <sink_block_id>blocks_sub_xx_2_0</sink_block_id>
+ <source_block_id>blks2_error_rate_0</source_block_id>
+ <sink_block_id>wxgui_numbersink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>analog_random_source_x_0</source_block_id>
- <sink_block_id>blocks_sub_xx_1_0</sink_block_id>
+ <source_block_id>virtual_source_0</source_block_id>
+ <sink_block_id>blks2_error_rate_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_multiply_const_vxx_2_0</source_block_id>
- <sink_block_id>blocks_sub_xx_2_0</sink_block_id>
+ <source_block_id>trellis_viterbi_combined_xx_1</source_block_id>
+ <sink_block_id>blks2_error_rate_0</sink_block_id>
<source_key>0</source_key>
<sink_key>1</sink_key>
</connection>
<connection>
- <source_block_id>trellis_encoder_xx_0</source_block_id>
- <sink_block_id>blocks_throttle_0</sink_block_id>
+ <source_block_id>trellis_viterbi_combined_xx_1</source_block_id>
+ <sink_block_id>virtual_sink_0_2</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>analog_noise_source_x_0</source_block_id>
- <sink_block_id>blocks_add_xx_1</sink_block_id>
- <source_key>0</source_key>
- <sink_key>1</sink_key>
- </connection>
- <connection>
- <source_block_id>blocks_throttle_0</source_block_id>
- <sink_block_id>digital_chunks_to_symbols_xx_0</sink_block_id>
+ <source_block_id>virtual_source_0_1</source_block_id>
+ <sink_block_id>trellis_viterbi_combined_xx_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>digital_chunks_to_symbols_xx_0</source_block_id>
- <sink_block_id>blocks_multiply_const_vxx_0</sink_block_id>
+ <source_block_id>analog_random_source_x_1</source_block_id>
+ <sink_block_id>virtual_sink_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>digital_chunks_to_symbols_xx_0_0</source_block_id>
- <sink_block_id>blocks_multiply_const_vxx_1</sink_block_id>
+ <source_block_id>analog_random_source_x_0</source_block_id>
+ <sink_block_id>virtual_sink_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
@@ -3584,80 +2535,62 @@
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>trellis_encoder_xx_2</source_block_id>
- <sink_block_id>digital_chunks_to_symbols_xx_0_0_0</sink_block_id>
- <source_key>0</source_key>
- <sink_key>0</sink_key>
- </connection>
- <connection>
- <source_block_id>digital_chunks_to_symbols_xx_0_0_0</source_block_id>
- <sink_block_id>blocks_multiply_const_vxx_2</sink_block_id>
- <source_key>0</source_key>
- <sink_key>0</sink_key>
- </connection>
- <connection>
- <source_block_id>trellis_encoder_xx_2_0</source_block_id>
- <sink_block_id>digital_chunks_to_symbols_xx_0_0_1</sink_block_id>
- <source_key>0</source_key>
- <sink_key>0</sink_key>
- </connection>
- <connection>
- <source_block_id>digital_chunks_to_symbols_xx_0_0_1</source_block_id>
- <sink_block_id>blocks_multiply_const_vxx_2_0</sink_block_id>
+ <source_block_id>digital_chunks_to_symbols_xx_0_0</source_block_id>
+ <sink_block_id>blocks_multiply_const_vxx_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_add_xx_1</source_block_id>
- <sink_block_id>qtgui_const_sink_x_0</sink_block_id>
+ <source_block_id>digital_chunks_to_symbols_xx_0</source_block_id>
+ <sink_block_id>blocks_multiply_const_vxx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_add_xx_1</source_block_id>
- <sink_block_id>trellis_viterbi_combined_xx_2</sink_block_id>
+ <source_block_id>blocks_throttle_0</source_block_id>
+ <sink_block_id>digital_chunks_to_symbols_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_short_to_float_0</source_block_id>
- <sink_block_id>qtgui_number_sink_0</sink_block_id>
+ <source_block_id>trellis_encoder_xx_0</source_block_id>
+ <sink_block_id>blocks_throttle_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_multiply_xx_2_0</source_block_id>
- <sink_block_id>blocks_short_to_float_1</sink_block_id>
+ <source_block_id>analog_random_source_x_0</source_block_id>
+ <sink_block_id>trellis_encoder_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_short_to_float_1</source_block_id>
- <sink_block_id>qtgui_number_sink_0_0_0_0</sink_block_id>
+ <source_block_id>analog_random_source_x_1</source_block_id>
+ <sink_block_id>trellis_encoder_xx_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_multiply_xx_1</source_block_id>
- <sink_block_id>blocks_short_to_float_2</sink_block_id>
+ <source_block_id>analog_noise_source_x_0</source_block_id>
+ <sink_block_id>blocks_add_xx_1</sink_block_id>
<source_key>0</source_key>
- <sink_key>0</sink_key>
+ <sink_key>1</sink_key>
</connection>
<connection>
- <source_block_id>blocks_short_to_float_2</source_block_id>
- <sink_block_id>qtgui_number_sink_0_0_0</sink_block_id>
+ <source_block_id>blocks_multiply_const_vxx_1</source_block_id>
+ <sink_block_id>blocks_add_xx_0</sink_block_id>
<source_key>0</source_key>
- <sink_key>0</sink_key>
+ <sink_key>1</sink_key>
</connection>
<connection>
- <source_block_id>blocks_multiply_xx_2</source_block_id>
- <sink_block_id>blocks_short_to_float_3</sink_block_id>
+ <source_block_id>blocks_add_xx_0</source_block_id>
+ <sink_block_id>blocks_add_xx_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_short_to_float_3</source_block_id>
- <sink_block_id>qtgui_number_sink_0_0</sink_block_id>
+ <source_block_id>blocks_multiply_const_vxx_0</source_block_id>
+ <sink_block_id>blocks_add_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
diff --git a/gr-trellis/examples/grc/pccc.grc b/gr-trellis/examples/grc/pccc.grc
index c642a71940..e10c70a614 100644
--- a/gr-trellis/examples/grc/pccc.grc
+++ b/gr-trellis/examples/grc/pccc.grc
@@ -1,6 +1,7 @@
<?xml version='1.0' encoding='ASCII'?>
+<?grc format='1' created='3.7.6'?>
<flow_graph>
- <timestamp>Mon Jul 28 14:02:43 2014</timestamp>
+ <timestamp>Fri Sep 26 12:26:16 2014</timestamp>
<block>
<key>options</key>
<param>
@@ -29,7 +30,7 @@
</param>
<param>
<key>generate_options</key>
- <value>qt_gui</value>
+ <value>wx_gui</value>
</param>
<param>
<key>category</key>
@@ -84,7 +85,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(520, 11)</value>
+ <value>(320, 21)</value>
</param>
<param>
<key>_rotation</key>
@@ -95,7 +96,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>noisevar</value>
+ <value>R</value>
</param>
<param>
<key>_enabled</key>
@@ -103,7 +104,7 @@
</param>
<param>
<key>value</key>
- <value>10**(-snr_db/10)</value>
+ <value>100e3</value>
</param>
<param>
<key>alias</key>
@@ -111,7 +112,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(279, 10)</value>
+ <value>(200, 101)</value>
</param>
<param>
<key>_rotation</key>
@@ -122,7 +123,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>R</value>
+ <value>block</value>
</param>
<param>
<key>_enabled</key>
@@ -130,7 +131,7 @@
</param>
<param>
<key>value</key>
- <value>100e3</value>
+ <value>1000</value>
</param>
<param>
<key>alias</key>
@@ -138,7 +139,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(358, 10)</value>
+ <value>(200, 37)</value>
</param>
<param>
<key>_rotation</key>
@@ -149,7 +150,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>block</value>
+ <value>dim</value>
</param>
<param>
<key>_enabled</key>
@@ -157,7 +158,7 @@
</param>
<param>
<key>value</key>
- <value>1000</value>
+ <value>mod[0]</value>
</param>
<param>
<key>alias</key>
@@ -165,7 +166,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(438, 10)</value>
+ <value>(688, 317)</value>
</param>
<param>
<key>_rotation</key>
@@ -173,54 +174,53 @@
</param>
</block>
<block>
- <key>analog_random_source_x</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>analog_random_source_x_0</value>
+ <value>constellation</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>short</value>
- </param>
- <param>
- <key>min</key>
- <value>0</value>
+ <key>value</key>
+ <value>mod[1]</value>
</param>
<param>
- <key>max</key>
- <value>2</value>
+ <key>alias</key>
+ <value></value>
</param>
<param>
- <key>num_samps</key>
- <value>1000</value>
+ <key>_coordinate</key>
+ <value>(528, 317)</value>
</param>
<param>
- <key>repeat</key>
- <value>True</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>variable</key>
<param>
- <key>alias</key>
- <value></value>
+ <key>id</key>
+ <value>dim</value>
</param>
<param>
- <key>affinity</key>
- <value></value>
+ <key>_enabled</key>
+ <value>False</value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
+ <key>value</key>
+ <value>2</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>alias</key>
+ <value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(21, 170)</value>
+ <value>(688, 189)</value>
</param>
<param>
<key>_rotation</key>
@@ -228,50 +228,53 @@
</param>
</block>
<block>
- <key>blocks_throttle</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>blocks_throttle_0</value>
+ <value>constellation</value>
</param>
<param>
<key>_enabled</key>
- <value>True</value>
+ <value>False</value>
</param>
<param>
- <key>type</key>
- <value>short</value>
+ <key>value</key>
+ <value>-3,-3,-1,-3,1,-3,3,-3, -3,-1,-1,-1,1,-1,3,-1, -3,1,-1,1,1,1,3,1, -3,3,-1,3,1,3,3,3 </value>
</param>
<param>
- <key>samples_per_second</key>
- <value>R</value>
+ <key>alias</key>
+ <value></value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>_coordinate</key>
+ <value>(528, 189)</value>
</param>
<param>
- <key>ignoretag</key>
- <value>True</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>variable</key>
<param>
- <key>alias</key>
- <value></value>
+ <key>id</key>
+ <value>Es</value>
</param>
<param>
- <key>affinity</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
+ <key>value</key>
+ <value>sum(numpy.square(constellation))/(len(constellation)/(1.0*dim))</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>alias</key>
+ <value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(559, 104)</value>
+ <value>(776, 141)</value>
</param>
<param>
<key>_rotation</key>
@@ -279,50 +282,45 @@
</param>
</block>
<block>
- <key>variable_qtgui_range</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>snr_db</value>
+ <value>noisevar</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>label</key>
- <value>SNR (dB)</value>
- </param>
- <param>
<key>value</key>
- <value>5</value>
- </param>
- <param>
- <key>start</key>
- <value>-10</value>
+ <value>10**(-EsN0_dB/10.0) * Es /2.0</value>
</param>
<param>
- <key>stop</key>
- <value>10</value>
+ <key>alias</key>
+ <value></value>
</param>
<param>
- <key>step</key>
- <value>0.01</value>
+ <key>_coordinate</key>
+ <value>(1032, 149)</value>
</param>
<param>
- <key>widget</key>
- <value>counter_slider</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>variable</key>
<param>
- <key>orient</key>
- <value>Qt.Horizontal</value>
+ <key>id</key>
+ <value>interleaver</value>
</param>
<param>
- <key>min_len</key>
- <value>200</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>gui_hint</key>
- <value></value>
+ <key>value</key>
+ <value>trellis.interleaver(block,666)</value>
</param>
<param>
<key>alias</key>
@@ -330,62 +328,61 @@
</param>
<param>
<key>_coordinate</key>
- <value>(177, 10)</value>
+ <value>(320, 213)</value>
</param>
<param>
<key>_rotation</key>
- <value>180</value>
+ <value>0</value>
</param>
</block>
<block>
- <key>digital_chunks_to_symbols_xx</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>digital_chunks_to_symbols_xx_0</value>
+ <value>fsm1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>in_type</key>
- <value>short</value>
- </param>
- <param>
- <key>out_type</key>
- <value>complex</value>
+ <key>value</key>
+ <value>trellis.fsm(prefix+"awgn1o2_4rsc.fsm")</value>
</param>
<param>
- <key>symbol_table</key>
- <value>-7,0, -5,0, -3,0, -1,0, 1,0, 3,0, 5,0, 7,0, 0,-7,0, -5,0, -3,0, -1,0, 1,0, 3,0, 5,0, 7,0</value>
+ <key>alias</key>
+ <value></value>
</param>
<param>
- <key>dimension</key>
- <value>2</value>
+ <key>_coordinate</key>
+ <value>(320, 85)</value>
</param>
<param>
- <key>num_ports</key>
- <value>1</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>variable</key>
<param>
- <key>alias</key>
- <value></value>
+ <key>id</key>
+ <value>fsm2</value>
</param>
<param>
- <key>affinity</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
+ <key>value</key>
+ <value>trellis.fsm(prefix+"awgn1o1_4rsc.fsm")</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>alias</key>
+ <value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(559, 180)</value>
+ <value>(320, 149)</value>
</param>
<param>
<key>_rotation</key>
@@ -393,62 +390,72 @@
</param>
</block>
<block>
- <key>trellis_pccc_encoder_xx</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>trellis_pccc_encoder_xx_0</value>
+ <value>mod</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>ss</value>
+ <key>value</key>
+ <value>fu.psk2x3</value>
</param>
<param>
- <key>o_fsm_args</key>
- <value>prefix + "/awgn1o2_4.fsm"</value>
+ <key>alias</key>
+ <value></value>
</param>
<param>
- <key>o_init_state</key>
+ <key>_coordinate</key>
+ <value>(576, 253)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_source</key>
<param>
- <key>i_fsm_args</key>
- <value>prefix + "/awgn1o2_4.fsm"</value>
+ <key>id</key>
+ <value>virtual_source_0_0</value>
</param>
<param>
- <key>i_init_state</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>interleaver_args</key>
- <value>trellis.interleaver(block,666)</value>
+ <key>stream_id</key>
+ <value>info</value>
</param>
<param>
- <key>bl</key>
- <value>block</value>
+ <key>_coordinate</key>
+ <value>(104, 1220)</value>
</param>
<param>
- <key>alias</key>
- <value></value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_source</key>
<param>
- <key>affinity</key>
- <value></value>
+ <key>id</key>
+ <value>virtual_source_0_0_0</value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>stream_id</key>
+ <value>estimate</value>
</param>
<param>
<key>_coordinate</key>
- <value>(234, 154)</value>
+ <value>(88, 1292)</value>
</param>
<param>
<key>_rotation</key>
@@ -456,10 +463,10 @@
</param>
</block>
<block>
- <key>trellis_pccc_decoder_combined_xx</key>
+ <key>wxgui_numbersink2</key>
<param>
<key>id</key>
- <value>trellis_pccc_decoder_combined_xx_0</value>
+ <value>wxgui_numbersink2_3_0_0</value>
</param>
<param>
<key>_enabled</key>
@@ -467,67 +474,71 @@
</param>
<param>
<key>type</key>
- <value>c</value>
+ <value>float</value>
</param>
<param>
- <key>out_type</key>
- <value>s</value>
+ <key>title</key>
+ <value>BER</value>
</param>
<param>
- <key>o_fsm_args</key>
- <value>prefix + "/awgn1o2_4.fsm"</value>
+ <key>units</key>
+ <value>BER</value>
</param>
<param>
- <key>o_init_state</key>
+ <key>samp_rate</key>
+ <value>R</value>
+ </param>
+ <param>
+ <key>min_value</key>
<value>0</value>
</param>
<param>
- <key>o_final_state</key>
- <value>-1</value>
+ <key>max_value</key>
+ <value>1.0</value>
</param>
<param>
- <key>i_fsm_args</key>
- <value>prefix + "/awgn1o2_4.fsm"</value>
+ <key>factor</key>
+ <value>1.0</value>
</param>
<param>
- <key>i_init_state</key>
- <value>0</value>
+ <key>decimal_places</key>
+ <value>6</value>
</param>
<param>
- <key>i_final_state</key>
- <value>-1</value>
+ <key>ref_level</key>
+ <value>0</value>
</param>
<param>
- <key>interleaver</key>
- <value>trellis.interleaver(block,666)</value>
+ <key>number_rate</key>
+ <value>15</value>
</param>
<param>
- <key>block_size</key>
- <value>block</value>
+ <key>peak_hold</key>
+ <value>False</value>
</param>
<param>
- <key>iterations</key>
- <value>10</value>
+ <key>average</key>
+ <value>False</value>
</param>
<param>
- <key>dim</key>
- <value>2</value>
+ <key>avg_alpha</key>
+ <value>0.001</value>
</param>
<param>
- <key>table</key>
- <value>-7,0, -5,0, -3,0, -1,0, 1,0, 3,0, 5,0, 7,0, 0,-7,0, -5,0, -3,0, -1,0, 1,0, 3,0, 5,0, 7,0</value>
+ <key>show_gauge</key>
+ <value>False</value>
</param>
<param>
- <key>metric_type</key>
- <value>digital.TRELLIS_EUCLIDEAN</value>
+ <key>win_size</key>
+ <value></value>
</param>
<param>
- <key>siso_type</key>
- <value>trellis.TRELLIS_MIN_SUM</value>
+ <key>grid_pos</key>
+ <value></value>
</param>
<param>
- <key>scaling</key>
- <value>1.0</value>
+ <key>notebook</key>
+ <value></value>
</param>
<param>
<key>alias</key>
@@ -538,27 +549,19 @@
<value></value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
- </param>
- <param>
- <key>maxoutbuf</key>
- <value>0</value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(234, 299)</value>
+ <value>(680, 1205)</value>
</param>
<param>
<key>_rotation</key>
- <value>180</value>
+ <value>0</value>
</param>
</block>
<block>
- <key>blocks_multiply_xx</key>
+ <key>blks2_error_rate</key>
<param>
<key>id</key>
- <value>blocks_multiply_xx_2_0</value>
+ <value>blks2_error_rate_0</value>
</param>
<param>
<key>_enabled</key>
@@ -566,14 +569,14 @@
</param>
<param>
<key>type</key>
- <value>short</value>
+ <value>'SER'</value>
</param>
<param>
- <key>num_inputs</key>
- <value>2</value>
+ <key>win_size</key>
+ <value>block*100</value>
</param>
<param>
- <key>vlen</key>
+ <key>bits_per_symbol</key>
<value>1</value>
</param>
<param>
@@ -594,7 +597,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(421, 574)</value>
+ <value>(304, 1256)</value>
</param>
<param>
<key>_rotation</key>
@@ -602,46 +605,68 @@
</param>
</block>
<block>
- <key>blocks_sub_xx</key>
+ <key>virtual_sink</key>
<param>
<key>id</key>
- <value>blocks_sub_xx_0</value>
+ <value>virtual_sink_0_1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>short</value>
+ <key>stream_id</key>
+ <value>estimate</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>_coordinate</key>
+ <value>(768, 940)</value>
</param>
<param>
- <key>num_inputs</key>
- <value>2</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_source</key>
<param>
- <key>alias</key>
- <value></value>
+ <key>id</key>
+ <value>virtual_source_0</value>
</param>
<param>
- <key>affinity</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
+ <key>stream_id</key>
+ <value>observation</value>
</param>
<param>
- <key>maxoutbuf</key>
+ <key>_coordinate</key>
+ <value>(104, 940)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_sink</key>
+ <param>
+ <key>id</key>
+ <value>virtual_sink_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>info</value>
+ </param>
<param>
<key>_coordinate</key>
- <value>(246, 580)</value>
+ <value>(224, 412)</value>
</param>
<param>
<key>_rotation</key>
@@ -649,22 +674,30 @@
</param>
</block>
<block>
- <key>blocks_short_to_float</key>
+ <key>blocks_throttle</key>
<param>
<key>id</key>
- <value>blocks_short_to_float_1_0</value>
+ <value>blocks_throttle_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
+ <key>type</key>
+ <value>byte</value>
+ </param>
+ <param>
+ <key>samples_per_second</key>
+ <value>R</value>
+ </param>
+ <param>
<key>vlen</key>
<value>1</value>
</param>
<param>
- <key>scale</key>
- <value>1</value>
+ <key>ignoretag</key>
+ <value>True</value>
</param>
<param>
<key>alias</key>
@@ -684,7 +717,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(564, 592)</value>
+ <value>(208, 492)</value>
</param>
<param>
<key>_rotation</key>
@@ -703,7 +736,7 @@
</param>
<param>
<key>type</key>
- <value>complex</value>
+ <value>float</value>
</param>
<param>
<key>noise_type</key>
@@ -711,7 +744,7 @@
</param>
<param>
<key>amp</key>
- <value>noisevar</value>
+ <value>noisevar**0.5</value>
</param>
<param>
<key>seed</key>
@@ -735,7 +768,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(520, 309)</value>
+ <value>(656, 646)</value>
</param>
<param>
<key>_rotation</key>
@@ -754,7 +787,7 @@
</param>
<param>
<key>type</key>
- <value>complex</value>
+ <value>float</value>
</param>
<param>
<key>num_inputs</key>
@@ -782,7 +815,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(816, 192)</value>
+ <value>(880, 552)</value>
</param>
<param>
<key>_rotation</key>
@@ -790,214 +823,360 @@
</param>
</block>
<block>
- <key>qtgui_number_sink</key>
+ <key>virtual_sink</key>
<param>
<key>id</key>
- <value>qtgui_number_sink_0</value>
+ <value>virtual_sink_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>name</key>
- <value>""</value>
+ <key>stream_id</key>
+ <value>observation</value>
</param>
<param>
- <key>type</key>
- <value>float</value>
+ <key>_coordinate</key>
+ <value>(896, 676)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>import</key>
+ <param>
+ <key>id</key>
+ <value>import_0_0</value>
</param>
<param>
- <key>autoscale</key>
+ <key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>avg</key>
- <value>0.001</value>
+ <key>import</key>
+ <value>import gnuradio.trellis.fsm_utils as fu</value>
</param>
<param>
- <key>graph_type</key>
- <value>qtgui.NUM_GRAPH_HORIZ</value>
+ <key>alias</key>
+ <value></value>
</param>
<param>
- <key>nconnections</key>
- <value>1</value>
+ <key>_coordinate</key>
+ <value>(48, 132)</value>
</param>
<param>
- <key>min</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>trellis_pccc_encoder_xx</key>
<param>
- <key>max</key>
- <value>1</value>
+ <key>id</key>
+ <value>trellis_pccc_encoder_xx_0</value>
</param>
<param>
- <key>update_time</key>
- <value>0.01</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>gui_hint</key>
- <value></value>
+ <key>type</key>
+ <value>bb</value>
</param>
<param>
- <key>label1</key>
- <value></value>
+ <key>o_fsm_args</key>
+ <value>fsm1</value>
</param>
<param>
- <key>unit1</key>
- <value></value>
+ <key>o_init_state</key>
+ <value>0</value>
</param>
<param>
- <key>color1</key>
- <value>("black", "black")</value>
+ <key>i_fsm_args</key>
+ <value>fsm2</value>
</param>
<param>
- <key>factor1</key>
- <value>1</value>
+ <key>i_init_state</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>interleaver_args</key>
+ <value>interleaver</value>
</param>
<param>
- <key>label2</key>
+ <key>bl</key>
+ <value>block</value>
+ </param>
+ <param>
+ <key>alias</key>
<value></value>
</param>
<param>
- <key>unit2</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>color2</key>
- <value>("black", "black")</value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>factor2</key>
- <value>1</value>
+ <key>maxoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>label3</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(400, 457)</value>
</param>
<param>
- <key>unit3</key>
- <value></value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>digital_chunks_to_symbols_xx</key>
<param>
- <key>color3</key>
- <value>("black", "black")</value>
+ <key>id</key>
+ <value>digital_chunks_to_symbols_xx_0</value>
</param>
<param>
- <key>factor3</key>
- <value>1</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>label4</key>
- <value></value>
+ <key>in_type</key>
+ <value>byte</value>
</param>
<param>
- <key>unit4</key>
- <value></value>
+ <key>out_type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>symbol_table</key>
+ <value>constellation</value>
</param>
<param>
- <key>color4</key>
- <value>("black", "black")</value>
+ <key>dimension</key>
+ <value>dim</value>
</param>
<param>
- <key>factor4</key>
+ <key>num_ports</key>
<value>1</value>
</param>
<param>
- <key>label5</key>
+ <key>alias</key>
<value></value>
</param>
<param>
- <key>unit5</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>color5</key>
- <value>("black", "black")</value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>factor5</key>
- <value>1</value>
+ <key>maxoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>label6</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(632, 485)</value>
</param>
<param>
- <key>unit6</key>
- <value></value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>analog_random_source_x</key>
<param>
- <key>color6</key>
- <value>("black", "black")</value>
+ <key>id</key>
+ <value>analog_random_source_x_0_0</value>
</param>
<param>
- <key>factor6</key>
- <value>1</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>label7</key>
- <value></value>
+ <key>type</key>
+ <value>byte</value>
</param>
<param>
- <key>unit7</key>
- <value></value>
+ <key>min</key>
+ <value>0</value>
</param>
<param>
- <key>color7</key>
- <value>("black", "black")</value>
+ <key>max</key>
+ <value>2</value>
</param>
<param>
- <key>factor7</key>
- <value>1</value>
+ <key>num_samps</key>
+ <value>block</value>
+ </param>
+ <param>
+ <key>repeat</key>
+ <value>True</value>
</param>
<param>
- <key>label8</key>
+ <key>alias</key>
<value></value>
</param>
<param>
- <key>unit8</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>color8</key>
- <value>("black", "black")</value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>factor8</key>
- <value>1</value>
+ <key>maxoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>label9</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(8, 471)</value>
</param>
<param>
- <key>unit9</key>
- <value></value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>variable_slider</key>
<param>
- <key>color9</key>
- <value>("black", "black")</value>
+ <key>id</key>
+ <value>EsN0_dB</value>
</param>
<param>
- <key>factor9</key>
- <value>1</value>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>EsN0 (dB)</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>2</value>
+ </param>
+ <param>
+ <key>min</key>
+ <value>-10</value>
+ </param>
+ <param>
+ <key>max</key>
+ <value>20</value>
+ </param>
+ <param>
+ <key>num_steps</key>
+ <value>1000</value>
+ </param>
+ <param>
+ <key>style</key>
+ <value>wx.SL_HORIZONTAL</value>
+ </param>
+ <param>
+ <key>converver</key>
+ <value>float_converter</value>
</param>
<param>
- <key>label10</key>
+ <key>grid_pos</key>
<value></value>
</param>
<param>
- <key>unit10</key>
+ <key>notebook</key>
<value></value>
</param>
<param>
- <key>color10</key>
- <value>("black", "black")</value>
+ <key>alias</key>
+ <value></value>
</param>
<param>
- <key>factor10</key>
- <value>1</value>
+ <key>_coordinate</key>
+ <value>(896, 129)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>trellis_pccc_decoder_combined_xx</key>
+ <param>
+ <key>id</key>
+ <value>trellis_pccc_decoder_combined_xx_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>f</value>
+ </param>
+ <param>
+ <key>out_type</key>
+ <value>b</value>
+ </param>
+ <param>
+ <key>o_fsm_args</key>
+ <value>fsm1</value>
+ </param>
+ <param>
+ <key>o_init_state</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>o_final_state</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>i_fsm_args</key>
+ <value>fsm2</value>
+ </param>
+ <param>
+ <key>i_init_state</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>i_final_state</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>interleaver</key>
+ <value>interleaver</value>
+ </param>
+ <param>
+ <key>block_size</key>
+ <value>block</value>
+ </param>
+ <param>
+ <key>iterations</key>
+ <value>10</value>
+ </param>
+ <param>
+ <key>dim</key>
+ <value>dim</value>
+ </param>
+ <param>
+ <key>table</key>
+ <value>constellation</value>
+ </param>
+ <param>
+ <key>metric_type</key>
+ <value>digital.TRELLIS_EUCLIDEAN</value>
+ </param>
+ <param>
+ <key>siso_type</key>
+ <value>trellis.TRELLIS_MIN_SUM</value>
+ </param>
+ <param>
+ <key>scaling</key>
+ <value>0.5/noisevar</value>
</param>
<param>
<key>alias</key>
@@ -1008,8 +1187,16 @@
<value></value>
</param>
<param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
<key>_coordinate</key>
- <value>(571, 477)</value>
+ <value>(400, 849)</value>
</param>
<param>
<key>_rotation</key>
@@ -1017,75 +1204,75 @@
</param>
</block>
<connection>
- <source_block_id>analog_random_source_x_0</source_block_id>
- <sink_block_id>trellis_pccc_encoder_xx_0</sink_block_id>
+ <source_block_id>digital_chunks_to_symbols_xx_0</source_block_id>
+ <sink_block_id>blocks_add_xx_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_add_xx_1</source_block_id>
- <sink_block_id>trellis_pccc_decoder_combined_xx_0</sink_block_id>
+ <source_block_id>blks2_error_rate_0</source_block_id>
+ <sink_block_id>wxgui_numbersink2_3_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>analog_noise_source_x_0</source_block_id>
- <sink_block_id>blocks_add_xx_1</sink_block_id>
+ <source_block_id>virtual_source_0_0</source_block_id>
+ <sink_block_id>blks2_error_rate_0</sink_block_id>
<source_key>0</source_key>
- <sink_key>1</sink_key>
+ <sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>digital_chunks_to_symbols_xx_0</source_block_id>
- <sink_block_id>blocks_add_xx_1</sink_block_id>
+ <source_block_id>virtual_source_0_0_0</source_block_id>
+ <sink_block_id>blks2_error_rate_0</sink_block_id>
<source_key>0</source_key>
- <sink_key>0</sink_key>
+ <sink_key>1</sink_key>
</connection>
<connection>
- <source_block_id>blocks_throttle_0</source_block_id>
- <sink_block_id>digital_chunks_to_symbols_xx_0</sink_block_id>
+ <source_block_id>blocks_add_xx_1</source_block_id>
+ <sink_block_id>virtual_sink_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>trellis_pccc_encoder_xx_0</source_block_id>
- <sink_block_id>blocks_throttle_0</sink_block_id>
+ <source_block_id>trellis_pccc_decoder_combined_xx_0</source_block_id>
+ <sink_block_id>virtual_sink_0_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>analog_random_source_x_0</source_block_id>
- <sink_block_id>blocks_sub_xx_0</sink_block_id>
+ <source_block_id>virtual_source_0</source_block_id>
+ <sink_block_id>trellis_pccc_decoder_combined_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_short_to_float_1_0</source_block_id>
- <sink_block_id>qtgui_number_sink_0</sink_block_id>
+ <source_block_id>trellis_pccc_encoder_xx_0</source_block_id>
+ <sink_block_id>digital_chunks_to_symbols_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>trellis_pccc_decoder_combined_xx_0</source_block_id>
- <sink_block_id>blocks_sub_xx_0</sink_block_id>
+ <source_block_id>blocks_throttle_0_0</source_block_id>
+ <sink_block_id>trellis_pccc_encoder_xx_0</sink_block_id>
<source_key>0</source_key>
- <sink_key>1</sink_key>
+ <sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_sub_xx_0</source_block_id>
- <sink_block_id>blocks_multiply_xx_2_0</sink_block_id>
+ <source_block_id>analog_random_source_x_0_0</source_block_id>
+ <sink_block_id>blocks_throttle_0_0</sink_block_id>
<source_key>0</source_key>
- <sink_key>1</sink_key>
+ <sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_sub_xx_0</source_block_id>
- <sink_block_id>blocks_multiply_xx_2_0</sink_block_id>
+ <source_block_id>analog_random_source_x_0_0</source_block_id>
+ <sink_block_id>virtual_sink_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_multiply_xx_2_0</source_block_id>
- <sink_block_id>blocks_short_to_float_1_0</sink_block_id>
+ <source_block_id>analog_noise_source_x_0</source_block_id>
+ <sink_block_id>blocks_add_xx_1</sink_block_id>
<source_key>0</source_key>
- <sink_key>0</sink_key>
+ <sink_key>1</sink_key>
</connection>
</flow_graph>
diff --git a/gr-trellis/examples/grc/readme.txt b/gr-trellis/examples/grc/readme.txt
index a5261ac0b2..3d32e046dd 100644
--- a/gr-trellis/examples/grc/readme.txt
+++ b/gr-trellis/examples/grc/readme.txt
@@ -1,6 +1,6 @@
These are examples of using gr-trellis in grc.
-INTERFERENCE CANCELLATION
+Interference Cancellation
-------------------------
Two users are transmitting simultaneously using convolutionally encoded QPSK, each with power P1=alpha*P and P2=(1-alpha)*P.
The combined signal is observed in noise and four different receivers are considered:
@@ -20,13 +20,13 @@ Serially Concatenated Convolutional Codes
-----------------------------------------
An SCCC can be defined by an outer and an inner FSM together with an interleaver
and a modulation type. You can change the SNR and observe the estimated BER.
-In sccc.grc the decoding and metric calculation are combined; in sccc1.grc they are separate.
Parallel Concatenated Convolutional Codes
-----------------------------------------
A PCCC can be defined by two FSMs together with an interleaver
and a modulation type. You can change the SNR and observe the estimated BER.
-In pccc1.grc the decoding and metric calculation are separate.
+
+...and a few other examples including turbo equalization, etc
Enjoy.
diff --git a/gr-trellis/examples/grc/sccc.grc b/gr-trellis/examples/grc/sccc.grc
index 9d516743b6..f31f3ce86d 100644
--- a/gr-trellis/examples/grc/sccc.grc
+++ b/gr-trellis/examples/grc/sccc.grc
@@ -1,6 +1,7 @@
<?xml version='1.0' encoding='ASCII'?>
+<?grc format='1' created='3.7.6'?>
<flow_graph>
- <timestamp>Mon Jul 28 14:09:50 2014</timestamp>
+ <timestamp>Wed Oct 1 11:04:18 2014</timestamp>
<block>
<key>options</key>
<param>
@@ -29,7 +30,7 @@
</param>
<param>
<key>generate_options</key>
- <value>qt_gui</value>
+ <value>wx_gui</value>
</param>
<param>
<key>category</key>
@@ -84,7 +85,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(514, 10)</value>
+ <value>(344, 13)</value>
</param>
<param>
<key>_rotation</key>
@@ -95,7 +96,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>block</value>
+ <value>mod</value>
</param>
<param>
<key>_enabled</key>
@@ -103,7 +104,7 @@
</param>
<param>
<key>value</key>
- <value>1000</value>
+ <value>fu.psk2x3</value>
</param>
<param>
<key>alias</key>
@@ -111,7 +112,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(441, 10)</value>
+ <value>(632, 101)</value>
</param>
<param>
<key>_rotation</key>
@@ -122,7 +123,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>R</value>
+ <value>interleaver</value>
</param>
<param>
<key>_enabled</key>
@@ -130,7 +131,7 @@
</param>
<param>
<key>value</key>
- <value>100e3</value>
+ <value>trellis.interleaver(block,666)</value>
</param>
<param>
<key>alias</key>
@@ -138,7 +139,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(358, 10)</value>
+ <value>(344, 205)</value>
</param>
<param>
<key>_rotation</key>
@@ -149,7 +150,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>noisevar</value>
+ <value>Es</value>
</param>
<param>
<key>_enabled</key>
@@ -157,7 +158,7 @@
</param>
<param>
<key>value</key>
- <value>10**(-snr_db/10)</value>
+ <value>sum(numpy.square(constellation))/(len(constellation)/(1.0*dim))</value>
</param>
<param>
<key>alias</key>
@@ -165,7 +166,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(279, 10)</value>
+ <value>(800, 133)</value>
</param>
<param>
<key>_rotation</key>
@@ -173,54 +174,80 @@
</param>
</block>
<block>
- <key>analog_random_source_x</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>analog_random_source_x_0</value>
+ <value>noisevar</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>short</value>
+ <key>value</key>
+ <value>10**(-EsN0_dB/10.0) * Es /2.0</value>
</param>
<param>
- <key>min</key>
- <value>0</value>
+ <key>alias</key>
+ <value></value>
</param>
<param>
- <key>max</key>
- <value>2</value>
+ <key>_coordinate</key>
+ <value>(1056, 141)</value>
</param>
<param>
- <key>num_samps</key>
- <value>1000</value>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>block</value>
</param>
<param>
- <key>repeat</key>
+ <key>_enabled</key>
<value>True</value>
</param>
<param>
+ <key>value</key>
+ <value>1000</value>
+ </param>
+ <param>
<key>alias</key>
<value></value>
</param>
<param>
- <key>affinity</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(224, 29)</value>
</param>
<param>
- <key>minoutbuf</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>variable</key>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>id</key>
+ <value>fsm_o</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>trellis.fsm(prefix+"awgn1o2_4.fsm")</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(21, 170)</value>
+ <value>(344, 77)</value>
</param>
<param>
<key>_rotation</key>
@@ -228,46 +255,80 @@
</param>
</block>
<block>
- <key>blocks_add_xx</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>blocks_add_xx_1</value>
+ <value>fsm_i</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>complex</value>
+ <key>value</key>
+ <value>trellis.fsm(prefix+"/awgn2o3_4.fsm")</value>
</param>
<param>
- <key>num_inputs</key>
- <value>2</value>
+ <key>alias</key>
+ <value></value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>_coordinate</key>
+ <value>(344, 141)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>constellation</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>mod[1]</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
- <key>affinity</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(568, 173)</value>
</param>
<param>
- <key>minoutbuf</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>variable</key>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>id</key>
+ <value>dim</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>mod[0]</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(951, 256)</value>
+ <value>(720, 173)</value>
</param>
<param>
<key>_rotation</key>
@@ -275,50 +336,76 @@
</param>
</block>
<block>
- <key>analog_noise_source_x</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>analog_noise_source_x_0</value>
+ <value>R</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>complex</value>
+ <key>value</key>
+ <value>100e3</value>
</param>
<param>
- <key>noise_type</key>
- <value>analog.GR_GAUSSIAN</value>
+ <key>alias</key>
+ <value></value>
</param>
<param>
- <key>amp</key>
- <value>noisevar</value>
+ <key>_coordinate</key>
+ <value>(224, 93)</value>
</param>
<param>
- <key>seed</key>
- <value>-42</value>
+ <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 numpy</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
- <key>affinity</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(32, 148)</value>
</param>
<param>
- <key>minoutbuf</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_sink</key>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>id</key>
+ <value>virtual_sink_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>info</value>
</param>
<param>
<key>_coordinate</key>
- <value>(549, 250)</value>
+ <value>(192, 332)</value>
</param>
<param>
<key>_rotation</key>
@@ -326,10 +413,10 @@
</param>
</block>
<block>
- <key>blocks_throttle</key>
+ <key>analog_random_source_x</key>
<param>
<key>id</key>
- <value>blocks_throttle_0</value>
+ <value>analog_random_source_x_0</value>
</param>
<param>
<key>_enabled</key>
@@ -337,18 +424,22 @@
</param>
<param>
<key>type</key>
- <value>short</value>
+ <value>byte</value>
</param>
<param>
- <key>samples_per_second</key>
- <value>R</value>
+ <key>min</key>
+ <value>0</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>max</key>
+ <value>2</value>
</param>
<param>
- <key>ignoretag</key>
+ <key>num_samps</key>
+ <value>1007</value>
+ </param>
+ <param>
+ <key>repeat</key>
<value>True</value>
</param>
<param>
@@ -369,7 +460,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(551, 116)</value>
+ <value>(5, 384)</value>
</param>
<param>
<key>_rotation</key>
@@ -377,10 +468,10 @@
</param>
</block>
<block>
- <key>blocks_sub_xx</key>
+ <key>blocks_throttle</key>
<param>
<key>id</key>
- <value>blocks_sub_xx_0</value>
+ <value>blocks_throttle_0</value>
</param>
<param>
<key>_enabled</key>
@@ -388,15 +479,19 @@
</param>
<param>
<key>type</key>
- <value>short</value>
+ <value>byte</value>
+ </param>
+ <param>
+ <key>samples_per_second</key>
+ <value>R</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
- <key>num_inputs</key>
- <value>2</value>
+ <key>ignoretag</key>
+ <value>True</value>
</param>
<param>
<key>alias</key>
@@ -416,7 +511,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(239, 548)</value>
+ <value>(232, 404)</value>
</param>
<param>
<key>_rotation</key>
@@ -424,25 +519,33 @@
</param>
</block>
<block>
- <key>blocks_multiply_xx</key>
+ <key>digital_chunks_to_symbols_xx</key>
<param>
<key>id</key>
- <value>blocks_multiply_xx_2_0</value>
+ <value>digital_chunks_to_symbols_xx_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>short</value>
+ <key>in_type</key>
+ <value>byte</value>
</param>
<param>
- <key>num_inputs</key>
- <value>2</value>
+ <key>out_type</key>
+ <value>float</value>
</param>
<param>
- <key>vlen</key>
+ <key>symbol_table</key>
+ <value>constellation</value>
+ </param>
+ <param>
+ <key>dimension</key>
+ <value>dim</value>
+ </param>
+ <param>
+ <key>num_ports</key>
<value>1</value>
</param>
<param>
@@ -463,7 +566,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(418, 551)</value>
+ <value>(672, 397)</value>
</param>
<param>
<key>_rotation</key>
@@ -471,21 +574,25 @@
</param>
</block>
<block>
- <key>blocks_short_to_float</key>
+ <key>blocks_add_xx</key>
<param>
<key>id</key>
- <value>blocks_short_to_float_1_0</value>
+ <value>blocks_add_xx_1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>num_inputs</key>
+ <value>2</value>
</param>
<param>
- <key>scale</key>
+ <key>vlen</key>
<value>1</value>
</param>
<param>
@@ -506,7 +613,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(605, 564)</value>
+ <value>(960, 472)</value>
</param>
<param>
<key>_rotation</key>
@@ -514,33 +621,25 @@
</param>
</block>
<block>
- <key>digital_chunks_to_symbols_xx</key>
+ <key>blks2_error_rate</key>
<param>
<key>id</key>
- <value>digital_chunks_to_symbols_xx_0</value>
+ <value>blks2_error_rate_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>in_type</key>
- <value>short</value>
- </param>
- <param>
- <key>out_type</key>
- <value>complex</value>
- </param>
- <param>
- <key>symbol_table</key>
- <value>1,0,1j,0,-1j,0,-1,0,1,0,1j,0,-1j,0,-1,0</value>
+ <key>type</key>
+ <value>'SER'</value>
</param>
<param>
- <key>dimension</key>
- <value>2</value>
+ <key>win_size</key>
+ <value>block*100</value>
</param>
<param>
- <key>num_ports</key>
+ <key>bits_per_symbol</key>
<value>1</value>
</param>
<param>
@@ -561,7 +660,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(551, 181)</value>
+ <value>(312, 1168)</value>
</param>
<param>
<key>_rotation</key>
@@ -569,226 +668,260 @@
</param>
</block>
<block>
- <key>qtgui_number_sink</key>
+ <key>virtual_source</key>
<param>
<key>id</key>
- <value>qtgui_number_sink_0</value>
+ <value>virtual_source_0_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>name</key>
- <value>""</value>
+ <key>stream_id</key>
+ <value>estimate</value>
</param>
<param>
- <key>type</key>
- <value>float</value>
+ <key>_coordinate</key>
+ <value>(96, 1204)</value>
</param>
<param>
- <key>autoscale</key>
- <value>False</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_source</key>
<param>
- <key>avg</key>
- <value>0.001</value>
+ <key>id</key>
+ <value>virtual_source_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>graph_type</key>
- <value>qtgui.NUM_GRAPH_HORIZ</value>
+ <key>stream_id</key>
+ <value>info</value>
</param>
<param>
- <key>nconnections</key>
- <value>1</value>
+ <key>_coordinate</key>
+ <value>(112, 1132)</value>
</param>
<param>
- <key>min</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>wxgui_numbersink2</key>
<param>
- <key>max</key>
- <value>1</value>
+ <key>id</key>
+ <value>wxgui_numbersink2_3_0_0</value>
</param>
<param>
- <key>update_time</key>
- <value>0.10</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>gui_hint</key>
- <value>1,0,1,1</value>
+ <key>type</key>
+ <value>float</value>
</param>
<param>
- <key>label1</key>
- <value></value>
+ <key>title</key>
+ <value>BER</value>
</param>
<param>
- <key>unit1</key>
- <value></value>
+ <key>units</key>
+ <value>BER</value>
</param>
<param>
- <key>color1</key>
- <value>("black", "black")</value>
+ <key>samp_rate</key>
+ <value>R</value>
</param>
<param>
- <key>factor1</key>
- <value>1</value>
+ <key>min_value</key>
+ <value>0</value>
</param>
<param>
- <key>label2</key>
- <value></value>
+ <key>max_value</key>
+ <value>1.0</value>
</param>
<param>
- <key>unit2</key>
- <value></value>
+ <key>factor</key>
+ <value>1.0</value>
</param>
<param>
- <key>color2</key>
- <value>("black", "black")</value>
+ <key>decimal_places</key>
+ <value>6</value>
</param>
<param>
- <key>factor2</key>
- <value>1</value>
+ <key>ref_level</key>
+ <value>0</value>
</param>
<param>
- <key>label3</key>
- <value></value>
+ <key>number_rate</key>
+ <value>15</value>
</param>
<param>
- <key>unit3</key>
- <value></value>
+ <key>peak_hold</key>
+ <value>False</value>
</param>
<param>
- <key>color3</key>
- <value>("black", "black")</value>
+ <key>average</key>
+ <value>False</value>
</param>
<param>
- <key>factor3</key>
- <value>1</value>
+ <key>avg_alpha</key>
+ <value>0.001</value>
</param>
<param>
- <key>label4</key>
- <value></value>
+ <key>show_gauge</key>
+ <value>False</value>
</param>
<param>
- <key>unit4</key>
+ <key>win_size</key>
<value></value>
</param>
<param>
- <key>color4</key>
- <value>("black", "black")</value>
+ <key>grid_pos</key>
+ <value></value>
</param>
<param>
- <key>factor4</key>
- <value>1</value>
+ <key>notebook</key>
+ <value></value>
</param>
<param>
- <key>label5</key>
+ <key>alias</key>
<value></value>
</param>
<param>
- <key>unit5</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>color5</key>
- <value>("black", "black")</value>
+ <key>_coordinate</key>
+ <value>(688, 1117)</value>
</param>
<param>
- <key>factor5</key>
- <value>1</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_source</key>
<param>
- <key>label6</key>
- <value></value>
+ <key>id</key>
+ <value>virtual_source_0</value>
</param>
<param>
- <key>unit6</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>color6</key>
- <value>("black", "black")</value>
+ <key>stream_id</key>
+ <value>observation</value>
</param>
<param>
- <key>factor6</key>
- <value>1</value>
+ <key>_coordinate</key>
+ <value>(88, 836)</value>
</param>
<param>
- <key>label7</key>
- <value></value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_sink</key>
<param>
- <key>unit7</key>
- <value></value>
+ <key>id</key>
+ <value>virtual_sink_0_1</value>
</param>
<param>
- <key>color7</key>
- <value>("black", "black")</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>factor7</key>
- <value>1</value>
+ <key>stream_id</key>
+ <value>estimate</value>
</param>
<param>
- <key>label8</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(744, 836)</value>
</param>
<param>
- <key>unit8</key>
- <value></value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>analog_noise_source_x</key>
<param>
- <key>color8</key>
- <value>("black", "black")</value>
+ <key>id</key>
+ <value>analog_noise_source_x_0</value>
</param>
<param>
- <key>factor8</key>
- <value>1</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>label9</key>
- <value></value>
+ <key>type</key>
+ <value>float</value>
</param>
<param>
- <key>unit9</key>
- <value></value>
+ <key>noise_type</key>
+ <value>analog.GR_GAUSSIAN</value>
</param>
<param>
- <key>color9</key>
- <value>("black", "black")</value>
+ <key>amp</key>
+ <value>noisevar**0.5</value>
</param>
<param>
- <key>factor9</key>
- <value>1</value>
+ <key>seed</key>
+ <value>-42</value>
</param>
<param>
- <key>label10</key>
+ <key>alias</key>
<value></value>
</param>
<param>
- <key>unit10</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>color10</key>
- <value>("black", "black")</value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>factor10</key>
- <value>1</value>
+ <key>maxoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>alias</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(608, 510)</value>
</param>
<param>
- <key>affinity</key>
- <value></value>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>virtual_sink</key>
+ <param>
+ <key>id</key>
+ <value>virtual_sink_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>observation</value>
</param>
<param>
<key>_coordinate</key>
- <value>(788, 548)</value>
+ <value>(1064, 484)</value>
</param>
<param>
<key>_rotation</key>
@@ -796,10 +929,10 @@
</param>
</block>
<block>
- <key>variable_qtgui_range</key>
+ <key>variable_slider</key>
<param>
<key>id</key>
- <value>snr_db</value>
+ <value>EsN0_dB</value>
</param>
<param>
<key>_enabled</key>
@@ -807,38 +940,38 @@
</param>
<param>
<key>label</key>
- <value>SNR (dB)</value>
+ <value>EsN0 (dB)</value>
</param>
<param>
<key>value</key>
- <value>5</value>
+ <value>2</value>
</param>
<param>
- <key>start</key>
+ <key>min</key>
<value>-10</value>
</param>
<param>
- <key>stop</key>
+ <key>max</key>
<value>10</value>
</param>
<param>
- <key>step</key>
- <value>0.01</value>
+ <key>num_steps</key>
+ <value>1000</value>
</param>
<param>
- <key>widget</key>
- <value>counter_slider</value>
+ <key>style</key>
+ <value>wx.SL_HORIZONTAL</value>
</param>
<param>
- <key>orient</key>
- <value>Qt.Horizontal</value>
+ <key>converver</key>
+ <value>float_converter</value>
</param>
<param>
- <key>min_len</key>
- <value>200</value>
+ <key>grid_pos</key>
+ <value></value>
</param>
<param>
- <key>gui_hint</key>
+ <key>notebook</key>
<value></value>
</param>
<param>
@@ -847,11 +980,11 @@
</param>
<param>
<key>_coordinate</key>
- <value>(177, 10)</value>
+ <value>(920, 113)</value>
</param>
<param>
<key>_rotation</key>
- <value>180</value>
+ <value>0</value>
</param>
</block>
<block>
@@ -866,11 +999,11 @@
</param>
<param>
<key>type</key>
- <value>ss</value>
+ <value>bb</value>
</param>
<param>
<key>o_fsm_args</key>
- <value>prefix+"/awgn1o2_4.fsm"</value>
+ <value>fsm_o</value>
</param>
<param>
<key>o_init_state</key>
@@ -878,7 +1011,7 @@
</param>
<param>
<key>i_fsm_args</key>
- <value>prefix+"/awgn2o3_4.fsm"</value>
+ <value>fsm_i</value>
</param>
<param>
<key>i_init_state</key>
@@ -886,7 +1019,7 @@
</param>
<param>
<key>interleaver_args</key>
- <value>trellis.interleaver(block,666)</value>
+ <value>interleaver</value>
</param>
<param>
<key>bl</key>
@@ -910,11 +1043,38 @@
</param>
<param>
<key>_coordinate</key>
- <value>(242, 154)</value>
+ <value>(416, 369)</value>
</param>
<param>
<key>_rotation</key>
- <value>180</value>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>import</key>
+ <param>
+ <key>id</key>
+ <value>import_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>import</key>
+ <value>import gnuradio.trellis.fsm_utils as fu</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(40, 204)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
</param>
</block>
<block>
@@ -929,15 +1089,15 @@
</param>
<param>
<key>type</key>
- <value>c</value>
+ <value>f</value>
</param>
<param>
<key>out_type</key>
- <value>s</value>
+ <value>b</value>
</param>
<param>
<key>o_fsm_args</key>
- <value>prefix+"/awgn1o2_4.fsm"</value>
+ <value>fsm_o</value>
</param>
<param>
<key>o_init_state</key>
@@ -949,7 +1109,7 @@
</param>
<param>
<key>i_fsm_args</key>
- <value>prefix+"/awgn2o3_4.fsm"</value>
+ <value>fsm_i</value>
</param>
<param>
<key>i_init_state</key>
@@ -961,7 +1121,7 @@
</param>
<param>
<key>interleaver</key>
- <value>trellis.interleaver(block,666)</value>
+ <value>interleaver</value>
</param>
<param>
<key>block_size</key>
@@ -973,11 +1133,11 @@
</param>
<param>
<key>dim</key>
- <value>2</value>
+ <value>dim</value>
</param>
<param>
<key>table</key>
- <value>1,0,1j,0,-1j,0,-1,0,1,0,1j,0,-1j,0,-1,0</value>
+ <value>constellation</value>
</param>
<param>
<key>metric_type</key>
@@ -985,11 +1145,11 @@
</param>
<param>
<key>siso_type</key>
- <value>trellis.TRELLIS_SUM_PRODUCT</value>
+ <value>trellis.TRELLIS_MIN_SUM</value>
</param>
<param>
<key>scaling</key>
- <value>1.0</value>
+ <value>1.0/noisevar</value>
</param>
<param>
<key>alias</key>
@@ -1009,7 +1169,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(241, 287)</value>
+ <value>(400, 745)</value>
</param>
<param>
<key>_rotation</key>
@@ -1017,74 +1177,74 @@
</param>
</block>
<connection>
- <source_block_id>analog_random_source_x_0</source_block_id>
- <sink_block_id>blocks_sub_xx_0</sink_block_id>
+ <source_block_id>analog_noise_source_x_0</source_block_id>
+ <sink_block_id>blocks_add_xx_1</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>1</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>digital_chunks_to_symbols_xx_0</source_block_id>
+ <sink_block_id>blocks_add_xx_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>analog_random_source_x_0</source_block_id>
- <sink_block_id>trellis_sccc_encoder_xx_0</sink_block_id>
+ <sink_block_id>virtual_sink_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>trellis_sccc_encoder_xx_0</source_block_id>
+ <source_block_id>analog_random_source_x_0</source_block_id>
<sink_block_id>blocks_throttle_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_add_xx_1</source_block_id>
- <sink_block_id>trellis_sccc_decoder_combined_xx_0</sink_block_id>
+ <source_block_id>blocks_throttle_0</source_block_id>
+ <sink_block_id>trellis_sccc_encoder_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>trellis_sccc_decoder_combined_xx_0</source_block_id>
- <sink_block_id>blocks_sub_xx_0</sink_block_id>
+ <source_block_id>trellis_sccc_encoder_xx_0</source_block_id>
+ <sink_block_id>digital_chunks_to_symbols_xx_0</sink_block_id>
<source_key>0</source_key>
- <sink_key>1</sink_key>
+ <sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_throttle_0</source_block_id>
- <sink_block_id>digital_chunks_to_symbols_xx_0</sink_block_id>
+ <source_block_id>blocks_add_xx_1</source_block_id>
+ <sink_block_id>virtual_sink_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>analog_noise_source_x_0</source_block_id>
- <sink_block_id>blocks_add_xx_1</sink_block_id>
+ <source_block_id>virtual_source_0_0_0</source_block_id>
+ <sink_block_id>blks2_error_rate_0</sink_block_id>
<source_key>0</source_key>
<sink_key>1</sink_key>
</connection>
<connection>
- <source_block_id>digital_chunks_to_symbols_xx_0</source_block_id>
- <sink_block_id>blocks_add_xx_1</sink_block_id>
+ <source_block_id>virtual_source_0_0</source_block_id>
+ <sink_block_id>blks2_error_rate_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_sub_xx_0</source_block_id>
- <sink_block_id>blocks_multiply_xx_2_0</sink_block_id>
- <source_key>0</source_key>
- <sink_key>1</sink_key>
- </connection>
- <connection>
- <source_block_id>blocks_sub_xx_0</source_block_id>
- <sink_block_id>blocks_multiply_xx_2_0</sink_block_id>
+ <source_block_id>blks2_error_rate_0</source_block_id>
+ <sink_block_id>wxgui_numbersink2_3_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_multiply_xx_2_0</source_block_id>
- <sink_block_id>blocks_short_to_float_1_0</sink_block_id>
+ <source_block_id>trellis_sccc_decoder_combined_xx_0</source_block_id>
+ <sink_block_id>virtual_sink_0_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_short_to_float_1_0</source_block_id>
- <sink_block_id>qtgui_number_sink_0</sink_block_id>
+ <source_block_id>virtual_source_0</source_block_id>
+ <sink_block_id>trellis_sccc_decoder_combined_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
diff --git a/gr-trellis/examples/grc/pccc1.grc b/gr-trellis/examples/grc/tcm.grc
index acb112d255..451d940962 100644
--- a/gr-trellis/examples/grc/pccc1.grc
+++ b/gr-trellis/examples/grc/tcm.grc
@@ -1,11 +1,12 @@
<?xml version='1.0' encoding='ASCII'?>
+<?grc format='1' created='3.7.6'?>
<flow_graph>
- <timestamp>Mon Jul 28 14:09:00 2014</timestamp>
+ <timestamp>Wed Oct 1 11:04:18 2014</timestamp>
<block>
<key>options</key>
<param>
<key>id</key>
- <value>sccc1</value>
+ <value>tcm</value>
</param>
<param>
<key>_enabled</key>
@@ -13,7 +14,7 @@
</param>
<param>
<key>title</key>
- <value>Parallel Concatenated Convolutional Code</value>
+ <value>Trellis Coded Modulation</value>
</param>
<param>
<key>author</key>
@@ -29,7 +30,7 @@
</param>
<param>
<key>generate_options</key>
- <value>qt_gui</value>
+ <value>wx_gui</value>
</param>
<param>
<key>category</key>
@@ -84,7 +85,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(513, 10)</value>
+ <value>(320, 13)</value>
</param>
<param>
<key>_rotation</key>
@@ -95,7 +96,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>block</value>
+ <value>dim</value>
</param>
<param>
<key>_enabled</key>
@@ -103,7 +104,7 @@
</param>
<param>
<key>value</key>
- <value>1000</value>
+ <value>mod[0]</value>
</param>
<param>
<key>alias</key>
@@ -111,7 +112,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(441, 10)</value>
+ <value>(464, 229)</value>
</param>
<param>
<key>_rotation</key>
@@ -122,7 +123,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>R</value>
+ <value>constellation</value>
</param>
<param>
<key>_enabled</key>
@@ -130,7 +131,7 @@
</param>
<param>
<key>value</key>
- <value>100e3</value>
+ <value>mod[1]</value>
</param>
<param>
<key>alias</key>
@@ -138,7 +139,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(358, 10)</value>
+ <value>(312, 229)</value>
</param>
<param>
<key>_rotation</key>
@@ -149,7 +150,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>noisevar</value>
+ <value>mod</value>
</param>
<param>
<key>_enabled</key>
@@ -157,7 +158,7 @@
</param>
<param>
<key>value</key>
- <value>10**(-snr_db/10)</value>
+ <value>fu.psk4</value>
</param>
<param>
<key>alias</key>
@@ -165,7 +166,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(279, 10)</value>
+ <value>(336, 157)</value>
</param>
<param>
<key>_rotation</key>
@@ -173,54 +174,53 @@
</param>
</block>
<block>
- <key>analog_random_source_x</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>analog_random_source_x_0</value>
+ <value>fsm</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>short</value>
- </param>
- <param>
- <key>min</key>
- <value>0</value>
+ <key>value</key>
+ <value>"awgn1o2_4.fsm"</value>
</param>
<param>
- <key>max</key>
- <value>2</value>
+ <key>alias</key>
+ <value></value>
</param>
<param>
- <key>num_samps</key>
- <value>1000</value>
+ <key>_coordinate</key>
+ <value>(320, 77)</value>
</param>
<param>
- <key>repeat</key>
- <value>True</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>variable</key>
<param>
- <key>alias</key>
- <value></value>
+ <key>id</key>
+ <value>R</value>
</param>
<param>
- <key>affinity</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
+ <key>value</key>
+ <value>100e3</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>alias</key>
+ <value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(21, 170)</value>
+ <value>(216, 109)</value>
</param>
<param>
<key>_rotation</key>
@@ -228,226 +228,270 @@
</param>
</block>
<block>
- <key>qtgui_number_sink</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>qtgui_number_sink_0</value>
+ <value>noisevar</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>name</key>
- <value>""</value>
+ <key>value</key>
+ <value>10**(-EsN0_dB/10.0) * Es /2.0</value>
</param>
<param>
- <key>type</key>
- <value>float</value>
+ <key>alias</key>
+ <value></value>
</param>
<param>
- <key>autoscale</key>
- <value>False</value>
+ <key>_coordinate</key>
+ <value>(728, 157)</value>
</param>
<param>
- <key>avg</key>
- <value>0.001</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>variable</key>
<param>
- <key>graph_type</key>
- <value>qtgui.NUM_GRAPH_HORIZ</value>
+ <key>id</key>
+ <value>Es</value>
</param>
<param>
- <key>nconnections</key>
- <value>1</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>min</key>
+ <key>value</key>
+ <value>sum(numpy.square(numpy.abs(constellation)))/(len(constellation)/(1.0*dim))</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(528, 157)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>variable</key>
<param>
- <key>max</key>
- <value>1</value>
+ <key>id</key>
+ <value>block</value>
</param>
<param>
- <key>update_time</key>
- <value>0.10</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>gui_hint</key>
- <value>1,0,1,1</value>
+ <key>value</key>
+ <value>500*16</value>
</param>
<param>
- <key>label1</key>
+ <key>alias</key>
<value></value>
</param>
<param>
- <key>unit1</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(216, 29)</value>
</param>
<param>
- <key>color1</key>
- <value>("black", "black")</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>blocks_throttle</key>
<param>
- <key>factor1</key>
- <value>1</value>
+ <key>id</key>
+ <value>blocks_throttle_0</value>
</param>
<param>
- <key>label2</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>unit2</key>
- <value></value>
+ <key>type</key>
+ <value>byte</value>
</param>
<param>
- <key>color2</key>
- <value>("black", "black")</value>
+ <key>samples_per_second</key>
+ <value>R</value>
</param>
<param>
- <key>factor2</key>
+ <key>vlen</key>
<value>1</value>
</param>
<param>
- <key>label3</key>
- <value></value>
+ <key>ignoretag</key>
+ <value>True</value>
</param>
<param>
- <key>unit3</key>
+ <key>alias</key>
<value></value>
</param>
<param>
- <key>color3</key>
- <value>("black", "black")</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
- <key>factor3</key>
- <value>1</value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>label4</key>
- <value></value>
+ <key>maxoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>unit4</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(208, 380)</value>
</param>
<param>
- <key>color4</key>
- <value>("black", "black")</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>blocks_add_xx</key>
<param>
- <key>factor4</key>
- <value>1</value>
+ <key>id</key>
+ <value>blocks_add_xx_1</value>
</param>
<param>
- <key>label5</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>unit5</key>
- <value></value>
+ <key>type</key>
+ <value>float</value>
</param>
<param>
- <key>color5</key>
- <value>("black", "black")</value>
+ <key>num_inputs</key>
+ <value>2</value>
</param>
<param>
- <key>factor5</key>
+ <key>vlen</key>
<value>1</value>
</param>
<param>
- <key>label6</key>
+ <key>alias</key>
<value></value>
</param>
<param>
- <key>unit6</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>color6</key>
- <value>("black", "black")</value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>factor6</key>
- <value>1</value>
+ <key>maxoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>label7</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(912, 488)</value>
</param>
<param>
- <key>unit7</key>
- <value></value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_sink</key>
<param>
- <key>color7</key>
- <value>("black", "black")</value>
+ <key>id</key>
+ <value>virtual_sink_0_0</value>
</param>
<param>
- <key>factor7</key>
- <value>1</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>label8</key>
- <value></value>
+ <key>stream_id</key>
+ <value>info</value>
</param>
<param>
- <key>unit8</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(224, 316)</value>
</param>
<param>
- <key>color8</key>
- <value>("black", "black")</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_sink</key>
<param>
- <key>factor8</key>
- <value>1</value>
+ <key>id</key>
+ <value>virtual_sink_0</value>
</param>
<param>
- <key>label9</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>unit9</key>
- <value></value>
+ <key>stream_id</key>
+ <value>observation</value>
</param>
<param>
- <key>color9</key>
- <value>("black", "black")</value>
+ <key>_coordinate</key>
+ <value>(832, 620)</value>
</param>
<param>
- <key>factor9</key>
- <value>1</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_source</key>
<param>
- <key>label10</key>
- <value></value>
+ <key>id</key>
+ <value>virtual_source_0</value>
</param>
<param>
- <key>unit10</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>color10</key>
- <value>("black", "black")</value>
+ <key>stream_id</key>
+ <value>observation</value>
</param>
<param>
- <key>factor10</key>
- <value>1</value>
+ <key>_coordinate</key>
+ <value>(64, 732)</value>
</param>
<param>
- <key>alias</key>
- <value></value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_sink</key>
<param>
- <key>affinity</key>
- <value></value>
+ <key>id</key>
+ <value>virtual_sink_0_1</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>estimate</value>
</param>
<param>
<key>_coordinate</key>
- <value>(632, 509)</value>
+ <value>(800, 732)</value>
</param>
<param>
<key>_rotation</key>
@@ -455,22 +499,30 @@
</param>
</block>
<block>
- <key>blocks_short_to_float</key>
+ <key>analog_noise_source_x</key>
<param>
<key>id</key>
- <value>blocks_short_to_float_1_0</value>
+ <value>analog_noise_source_x_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>type</key>
+ <value>float</value>
</param>
<param>
- <key>scale</key>
- <value>1</value>
+ <key>noise_type</key>
+ <value>analog.GR_GAUSSIAN</value>
+ </param>
+ <param>
+ <key>amp</key>
+ <value>noisevar**0.5</value>
+ </param>
+ <param>
+ <key>seed</key>
+ <value>-42</value>
</param>
<param>
<key>alias</key>
@@ -490,7 +542,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(375, 525)</value>
+ <value>(384, 502)</value>
</param>
<param>
<key>_rotation</key>
@@ -498,46 +550,58 @@
</param>
</block>
<block>
- <key>blocks_multiply_xx</key>
+ <key>variable_slider</key>
<param>
<key>id</key>
- <value>blocks_multiply_xx_2_0</value>
+ <value>EsN0_dB</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>short</value>
+ <key>label</key>
+ <value>Es/N0 (dB)</value>
</param>
<param>
- <key>num_inputs</key>
- <value>2</value>
+ <key>value</key>
+ <value>4.0</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>min</key>
+ <value>-10</value>
</param>
<param>
- <key>alias</key>
- <value></value>
+ <key>max</key>
+ <value>30</value>
</param>
<param>
- <key>affinity</key>
+ <key>num_steps</key>
+ <value>1000</value>
+ </param>
+ <param>
+ <key>style</key>
+ <value>wx.SL_HORIZONTAL</value>
+ </param>
+ <param>
+ <key>converver</key>
+ <value>float_converter</value>
+ </param>
+ <param>
+ <key>grid_pos</key>
<value></value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
+ <key>notebook</key>
+ <value></value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>alias</key>
+ <value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(232, 507)</value>
+ <value>(608, 105)</value>
</param>
<param>
<key>_rotation</key>
@@ -545,10 +609,10 @@
</param>
</block>
<block>
- <key>blocks_sub_xx</key>
+ <key>analog_random_source_x</key>
<param>
<key>id</key>
- <value>blocks_sub_xx_0</value>
+ <value>analog_random_source_x_0</value>
</param>
<param>
<key>_enabled</key>
@@ -556,17 +620,25 @@
</param>
<param>
<key>type</key>
- <value>short</value>
+ <value>byte</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>min</key>
+ <value>0</value>
</param>
<param>
- <key>num_inputs</key>
+ <key>max</key>
<value>2</value>
</param>
<param>
+ <key>num_samps</key>
+ <value>1007</value>
+ </param>
+ <param>
+ <key>repeat</key>
+ <value>True</value>
+ </param>
+ <param>
<key>alias</key>
<value></value>
</param>
@@ -584,7 +656,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(57, 513)</value>
+ <value>(8, 359)</value>
</param>
<param>
<key>_rotation</key>
@@ -592,49 +664,81 @@
</param>
</block>
<block>
- <key>variable_qtgui_range</key>
+ <key>wxgui_numbersink2</key>
<param>
<key>id</key>
- <value>snr_db</value>
+ <value>wxgui_numbersink2_3_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>label</key>
- <value>SNR (dB)</value>
+ <key>type</key>
+ <value>float</value>
</param>
<param>
- <key>value</key>
- <value>5</value>
+ <key>title</key>
+ <value>BER</value>
</param>
<param>
- <key>start</key>
- <value>-10</value>
+ <key>units</key>
+ <value>BER</value>
+ </param>
+ <param>
+ <key>samp_rate</key>
+ <value>R</value>
+ </param>
+ <param>
+ <key>min_value</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>max_value</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>factor</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>decimal_places</key>
+ <value>6</value>
+ </param>
+ <param>
+ <key>ref_level</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>number_rate</key>
+ <value>15</value>
+ </param>
+ <param>
+ <key>peak_hold</key>
+ <value>False</value>
</param>
<param>
- <key>stop</key>
- <value>10</value>
+ <key>average</key>
+ <value>False</value>
</param>
<param>
- <key>step</key>
- <value>0.01</value>
+ <key>avg_alpha</key>
+ <value>0.001</value>
</param>
<param>
- <key>widget</key>
- <value>counter_slider</value>
+ <key>show_gauge</key>
+ <value>False</value>
</param>
<param>
- <key>orient</key>
- <value>Qt.Horizontal</value>
+ <key>win_size</key>
+ <value></value>
</param>
<param>
- <key>min_len</key>
- <value>200</value>
+ <key>grid_pos</key>
+ <value></value>
</param>
<param>
- <key>gui_hint</key>
+ <key>notebook</key>
<value></value>
</param>
<param>
@@ -642,51 +746,85 @@
<value></value>
</param>
<param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
<key>_coordinate</key>
- <value>(177, 10)</value>
+ <value>(728, 1133)</value>
</param>
<param>
<key>_rotation</key>
- <value>180</value>
+ <value>0</value>
</param>
</block>
<block>
- <key>trellis_pccc_encoder_xx</key>
+ <key>virtual_source</key>
<param>
<key>id</key>
- <value>trellis_pccc_encoder_xx_0</value>
+ <value>virtual_source_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>ss</value>
+ <key>stream_id</key>
+ <value>info</value>
</param>
<param>
- <key>o_fsm_args</key>
- <value>prefix+"/awgn1o2_4.fsm"</value>
+ <key>_coordinate</key>
+ <value>(80, 1148)</value>
</param>
<param>
- <key>o_init_state</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_source</key>
<param>
- <key>i_fsm_args</key>
- <value>prefix+"/awgn1o2_4.fsm"</value>
+ <key>id</key>
+ <value>virtual_source_0_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>estimate</value>
</param>
<param>
- <key>i_init_state</key>
+ <key>_coordinate</key>
+ <value>(72, 1244)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>blks2_error_rate</key>
<param>
- <key>interleaver_args</key>
- <value>trellis.interleaver(block,666)</value>
+ <key>id</key>
+ <value>blks2_error_rate_0</value>
</param>
<param>
- <key>bl</key>
- <value>block</value>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>'SER'</value>
+ </param>
+ <param>
+ <key>win_size</key>
+ <value>block*100</value>
+ </param>
+ <param>
+ <key>bits_per_symbol</key>
+ <value>1</value>
</param>
<param>
<key>alias</key>
@@ -706,7 +844,34 @@
</param>
<param>
<key>_coordinate</key>
- <value>(235, 154)</value>
+ <value>(312, 1184)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>note</key>
+ <param>
+ <key>id</key>
+ <value>note_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>note</key>
+ <value>Substititue the metrics/Viterbi block with Viterbi_combo</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(712, 868)</value>
</param>
<param>
<key>_rotation</key>
@@ -721,7 +886,7 @@
</param>
<param>
<key>_enabled</key>
- <value>True</value>
+ <value>False</value>
</param>
<param>
<key>type</key>
@@ -729,15 +894,15 @@
</param>
<param>
<key>card</key>
- <value>16</value>
+ <value>trellis.fsm(prefix+fsm).O()</value>
</param>
<param>
<key>dim</key>
- <value>2</value>
+ <value>dim</value>
</param>
<param>
<key>table</key>
- <value>-7,0, -5,0, -3,0, -1,0, 1,0, 3,0, 5,0, 7,0, 0,-7,0, -5,0, -3,0, -1,0, 1,0, 3,0, 5,0, 7,0</value>
+ <value>constellation</value>
</param>
<param>
<key>metric_type</key>
@@ -761,7 +926,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(89, 380)</value>
+ <value>(304, 711)</value>
</param>
<param>
<key>_rotation</key>
@@ -769,58 +934,34 @@
</param>
</block>
<block>
- <key>trellis_pccc_decoder_x</key>
+ <key>trellis_viterbi_x</key>
<param>
<key>id</key>
- <value>trellis_pccc_decoder_x_0</value>
+ <value>trellis_viterbi_x_0</value>
</param>
<param>
<key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>out_type</key>
- <value>s</value>
- </param>
- <param>
- <key>o_fsm_args</key>
- <value>prefix+"/awgn1o2_4.fsm"</value>
- </param>
- <param>
- <key>o_init_state</key>
- <value>0</value>
- </param>
- <param>
- <key>o_final_state</key>
- <value>-1</value>
- </param>
- <param>
- <key>i_fsm_args</key>
- <value>prefix+"/awgn1o2_4.fsm"</value>
- </param>
- <param>
- <key>i_init_state</key>
- <value>0</value>
+ <value>False</value>
</param>
<param>
- <key>i_final_state</key>
- <value>-1</value>
+ <key>type</key>
+ <value>b</value>
</param>
<param>
- <key>interleaver</key>
- <value>trellis.interleaver(block,666)</value>
+ <key>fsm_args</key>
+ <value>prefix+fsm</value>
</param>
<param>
<key>block_size</key>
<value>block</value>
</param>
<param>
- <key>iterations</key>
- <value>10</value>
+ <key>init_state</key>
+ <value>-1</value>
</param>
<param>
- <key>siso_type</key>
- <value>trellis.TRELLIS_MIN_SUM</value>
+ <key>final_state</key>
+ <value>-1</value>
</param>
<param>
<key>alias</key>
@@ -840,7 +981,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(379, 332)</value>
+ <value>(544, 711)</value>
</param>
<param>
<key>_rotation</key>
@@ -848,34 +989,50 @@
</param>
</block>
<block>
- <key>digital_chunks_to_symbols_xx</key>
+ <key>trellis_viterbi_combined_xx</key>
<param>
<key>id</key>
- <value>digital_chunks_to_symbols_xx_0</value>
+ <value>trellis_viterbi_combined_xx_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>in_type</key>
- <value>short</value>
+ <key>type</key>
+ <value>f</value>
</param>
<param>
<key>out_type</key>
- <value>float</value>
+ <value>b</value>
</param>
<param>
- <key>symbol_table</key>
- <value>-7,0,-5,0,-3,0,-1,0,1,0,3,0,5,0,7,0,-7,0,-5,0,-3,0,-1,0,1,0,3,0,5,0,7,0</value>
+ <key>fsm_args</key>
+ <value>prefix+fsm</value>
</param>
<param>
- <key>dimension</key>
- <value>2</value>
+ <key>block_size</key>
+ <value>block</value>
</param>
<param>
- <key>num_ports</key>
- <value>1</value>
+ <key>init_state</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>final_state</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>dim</key>
+ <value>dim</value>
+ </param>
+ <param>
+ <key>table</key>
+ <value>constellation</value>
+ </param>
+ <param>
+ <key>metric_type</key>
+ <value>digital.TRELLIS_EUCLIDEAN</value>
</param>
<param>
<key>alias</key>
@@ -895,7 +1052,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(552, 164)</value>
+ <value>(440, 866)</value>
</param>
<param>
<key>_rotation</key>
@@ -903,50 +1060,53 @@
</param>
</block>
<block>
- <key>blocks_throttle</key>
+ <key>import</key>
<param>
<key>id</key>
- <value>blocks_throttle_0</value>
+ <value>import_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>short</value>
+ <key>import</key>
+ <value>import numpy</value>
</param>
<param>
- <key>samples_per_second</key>
- <value>R</value>
+ <key>alias</key>
+ <value></value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>_coordinate</key>
+ <value>(16, 140)</value>
</param>
<param>
- <key>ignoretag</key>
- <value>True</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>import</key>
<param>
- <key>alias</key>
- <value></value>
+ <key>id</key>
+ <value>import_0_0</value>
</param>
<param>
- <key>affinity</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
+ <key>import</key>
+ <value>import gnuradio.trellis.fsm_utils as fu</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>alias</key>
+ <value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(553, 89)</value>
+ <value>(24, 196)</value>
</param>
<param>
<key>_rotation</key>
@@ -954,30 +1114,34 @@
</param>
</block>
<block>
- <key>analog_noise_source_x</key>
+ <key>digital_chunks_to_symbols_xx</key>
<param>
<key>id</key>
- <value>analog_noise_source_x_0</value>
+ <value>digital_chunks_to_symbols_xx_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
+ <key>in_type</key>
+ <value>byte</value>
+ </param>
+ <param>
+ <key>out_type</key>
<value>float</value>
</param>
<param>
- <key>noise_type</key>
- <value>analog.GR_GAUSSIAN</value>
+ <key>symbol_table</key>
+ <value>constellation</value>
</param>
<param>
- <key>amp</key>
- <value>noisevar</value>
+ <key>dimension</key>
+ <value>dim</value>
</param>
<param>
- <key>seed</key>
- <value>-42</value>
+ <key>num_ports</key>
+ <value>1</value>
</param>
<param>
<key>alias</key>
@@ -997,7 +1161,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(551, 230)</value>
+ <value>(696, 373)</value>
</param>
<param>
<key>_rotation</key>
@@ -1005,10 +1169,10 @@
</param>
</block>
<block>
- <key>blocks_add_xx</key>
+ <key>trellis_encoder_xx</key>
<param>
<key>id</key>
- <value>blocks_add_xx_1</value>
+ <value>trellis_encoder_xx_0</value>
</param>
<param>
<key>_enabled</key>
@@ -1016,15 +1180,23 @@
</param>
<param>
<key>type</key>
- <value>float</value>
+ <value>bb</value>
</param>
<param>
- <key>num_inputs</key>
- <value>2</value>
+ <key>fsm_args</key>
+ <value>prefix+fsm</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>init_state</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>blockwise</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>blocklength</key>
+ <value>0</value>
</param>
<param>
<key>alias</key>
@@ -1044,7 +1216,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(839, 176)</value>
+ <value>(424, 373)</value>
</param>
<param>
<key>_rotation</key>
@@ -1052,81 +1224,93 @@
</param>
</block>
<connection>
- <source_block_id>analog_random_source_x_0</source_block_id>
- <sink_block_id>blocks_sub_xx_0</sink_block_id>
+ <source_block_id>analog_noise_source_x_0</source_block_id>
+ <sink_block_id>blocks_add_xx_1</sink_block_id>
<source_key>0</source_key>
- <sink_key>0</sink_key>
+ <sink_key>1</sink_key>
</connection>
<connection>
- <source_block_id>blocks_add_xx_1</source_block_id>
- <sink_block_id>trellis_metrics_x_0</sink_block_id>
+ <source_block_id>digital_chunks_to_symbols_xx_0</source_block_id>
+ <sink_block_id>blocks_add_xx_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>analog_random_source_x_0</source_block_id>
- <sink_block_id>trellis_pccc_encoder_xx_0</sink_block_id>
+ <sink_block_id>blocks_throttle_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>trellis_pccc_encoder_xx_0</source_block_id>
- <sink_block_id>blocks_throttle_0</sink_block_id>
+ <source_block_id>blocks_throttle_0</source_block_id>
+ <sink_block_id>trellis_encoder_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>trellis_metrics_x_0</source_block_id>
- <sink_block_id>trellis_pccc_decoder_x_0</sink_block_id>
+ <source_block_id>trellis_encoder_xx_0</source_block_id>
+ <sink_block_id>digital_chunks_to_symbols_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>trellis_pccc_decoder_x_0</source_block_id>
- <sink_block_id>blocks_sub_xx_0</sink_block_id>
+ <source_block_id>blocks_add_xx_1</source_block_id>
+ <sink_block_id>virtual_sink_0</sink_block_id>
<source_key>0</source_key>
- <sink_key>1</sink_key>
+ <sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_short_to_float_1_0</source_block_id>
- <sink_block_id>qtgui_number_sink_0</sink_block_id>
+ <source_block_id>virtual_source_0</source_block_id>
+ <sink_block_id>trellis_metrics_x_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_sub_xx_0</source_block_id>
- <sink_block_id>blocks_multiply_xx_2_0</sink_block_id>
+ <source_block_id>trellis_metrics_x_0</source_block_id>
+ <sink_block_id>trellis_viterbi_x_0</sink_block_id>
<source_key>0</source_key>
- <sink_key>1</sink_key>
+ <sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_sub_xx_0</source_block_id>
- <sink_block_id>blocks_multiply_xx_2_0</sink_block_id>
+ <source_block_id>analog_random_source_x_0</source_block_id>
+ <sink_block_id>virtual_sink_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_multiply_xx_2_0</source_block_id>
- <sink_block_id>blocks_short_to_float_1_0</sink_block_id>
+ <source_block_id>trellis_viterbi_x_0</source_block_id>
+ <sink_block_id>virtual_sink_0_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>analog_noise_source_x_0</source_block_id>
- <sink_block_id>blocks_add_xx_1</sink_block_id>
+ <source_block_id>virtual_source_0</source_block_id>
+ <sink_block_id>trellis_viterbi_combined_xx_0</sink_block_id>
<source_key>0</source_key>
- <sink_key>1</sink_key>
+ <sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>digital_chunks_to_symbols_xx_0</source_block_id>
- <sink_block_id>blocks_add_xx_1</sink_block_id>
+ <source_block_id>trellis_viterbi_combined_xx_0</source_block_id>
+ <sink_block_id>virtual_sink_0_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_throttle_0</source_block_id>
- <sink_block_id>digital_chunks_to_symbols_xx_0</sink_block_id>
+ <source_block_id>blks2_error_rate_0</source_block_id>
+ <sink_block_id>wxgui_numbersink2_3_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
+ <connection>
+ <source_block_id>virtual_source_0_0</source_block_id>
+ <sink_block_id>blks2_error_rate_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>virtual_source_0_0_0</source_block_id>
+ <sink_block_id>blks2_error_rate_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>1</sink_key>
+ </connection>
</flow_graph>
diff --git a/gr-trellis/examples/grc/turbo_equalization.grc b/gr-trellis/examples/grc/turbo_equalization.grc
new file mode 100644
index 0000000000..c83c59db20
--- /dev/null
+++ b/gr-trellis/examples/grc/turbo_equalization.grc
@@ -0,0 +1,2766 @@
+<?xml version='1.0' encoding='ASCII'?>
+<?grc format='1' created='3.7.6'?>
+<flow_graph>
+ <timestamp>Wed Oct 1 11:04:18 2014</timestamp>
+ <block>
+ <key>options</key>
+ <param>
+ <key>id</key>
+ <value>turbo_equalization</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value>Hard/Soft/Turbo Equalization</value>
+ </param>
+ <param>
+ <key>author</key>
+ <value>AA</value>
+ </param>
+ <param>
+ <key>description</key>
+ <value>gnuradio flow graph</value>
+ </param>
+ <param>
+ <key>window_size</key>
+ <value>2048, 3048</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>max_nouts</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>realtime_scheduling</key>
+ <value></value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(10, 10)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>fsm_o</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>trellis.fsm(prefix+"/awgn1o2_4.fsm")</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(344, 21)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>block_b</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>bpsym*1000</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(216, 21)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>interleaver</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>trellis.interleaver(block_b/bpsym,666)</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(528, 117)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>Es</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>numpy.mean((numpy.square(numpy.abs(tot_mod[1]))))</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(776, 181)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>noisevar</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>10**(-EsN0_dB/10.0) * Es /2.0</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(1080, 181)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>bpsym</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>int(round(math.log(fsm_o.I())/math.log(2)))</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(528, 29)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>channel</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>fu.c_channel</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(320, 205)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>modulation</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>fu.pam4</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(320, 117)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>R</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>100e3</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(216, 109)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>tot_mod</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>fu.make_isi_lookup(modulation,channel,False)</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(320, 381)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>prefix</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>"@FSM_FILE_INSTALL_DIR@"</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(768, 21)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>fsm_i</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>trellis.fsm(len(modulation[1]),len(channel))</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(320, 293)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>import</key>
+ <param>
+ <key>id</key>
+ <value>import_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>import</key>
+ <value>import gnuradio.trellis.fsm_utils as fu</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(24, 252)</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 numpy</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(16, 140)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>import</key>
+ <param>
+ <key>id</key>
+ <value>import_0_1</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>import</key>
+ <value>import math</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(24, 188)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>virtual_sink</key>
+ <param>
+ <key>id</key>
+ <value>virtual_sink_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>observation</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(608, 1076)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_add_xx</key>
+ <param>
+ <key>id</key>
+ <value>blocks_add_xx_1</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>num_inputs</key>
+ <value>2</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(688, 944)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>analog_noise_source_x</key>
+ <param>
+ <key>id</key>
+ <value>analog_noise_source_x_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>noise_type</key>
+ <value>analog.GR_GAUSSIAN</value>
+ </param>
+ <param>
+ <key>amp</key>
+ <value>noisevar**0.5</value>
+ </param>
+ <param>
+ <key>seed</key>
+ <value>-42</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(288, 958)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>fir_filter_xxx</key>
+ <param>
+ <key>id</key>
+ <value>fir_filter_xxx_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>fff</value>
+ </param>
+ <param>
+ <key>decim</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>taps</key>
+ <value>fu.c_channel</value>
+ </param>
+ <param>
+ <key>samp_delay</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(448, 861)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>digital_chunks_to_symbols_xx</key>
+ <param>
+ <key>id</key>
+ <value>digital_chunks_to_symbols_xx_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>in_type</key>
+ <value>byte</value>
+ </param>
+ <param>
+ <key>out_type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>symbol_table</key>
+ <value>modulation[1]</value>
+ </param>
+ <param>
+ <key>dimension</key>
+ <value>modulation[0]</value>
+ </param>
+ <param>
+ <key>num_ports</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(480, 733)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>trellis_permutation</key>
+ <param>
+ <key>id</key>
+ <value>trellis_permutation_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>byte</value>
+ </param>
+ <param>
+ <key>interleaver_size</key>
+ <value>interleaver.K()</value>
+ </param>
+ <param>
+ <key>table</key>
+ <value>interleaver.INTER()</value>
+ </param>
+ <param>
+ <key>syms_per_block</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(208, 726)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>virtual_sink</key>
+ <param>
+ <key>id</key>
+ <value>virtual_sink_0_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>info_i</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(968, 572)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_throttle</key>
+ <param>
+ <key>id</key>
+ <value>blocks_throttle_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>byte</value>
+ </param>
+ <param>
+ <key>samples_per_second</key>
+ <value>R</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>ignoretag</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(256, 580)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>analog_random_source_x</key>
+ <param>
+ <key>id</key>
+ <value>analog_random_source_x_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>byte</value>
+ </param>
+ <param>
+ <key>min</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>max</key>
+ <value>2</value>
+ </param>
+ <param>
+ <key>num_samps</key>
+ <value>1007</value>
+ </param>
+ <param>
+ <key>repeat</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(16, 559)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_pack_k_bits_bb</key>
+ <param>
+ <key>id</key>
+ <value>blocks_pack_k_bits_bb_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>k</key>
+ <value>bpsym</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(440, 580)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>trellis_encoder_xx</key>
+ <param>
+ <key>id</key>
+ <value>trellis_encoder_xx_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>bb</value>
+ </param>
+ <param>
+ <key>fsm_args</key>
+ <value>fsm_o</value>
+ </param>
+ <param>
+ <key>init_state</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>blockwise</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>blocklength</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(672, 573)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>virtual_sink</key>
+ <param>
+ <key>id</key>
+ <value>virtual_sink_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>info</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(248, 524)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>virtual_sink</key>
+ <param>
+ <key>id</key>
+ <value>virtual_sink_0_1</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>estimate</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(864, 1380)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_unpack_k_bits_bb</key>
+ <param>
+ <key>id</key>
+ <value>blocks_unpack_k_bits_bb_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>k</key>
+ <value>bpsym</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(552, 1380)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_char_to_float</key>
+ <param>
+ <key>id</key>
+ <value>blocks_char_to_float_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>scale</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(72, 1380)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>trellis_permutation</key>
+ <param>
+ <key>id</key>
+ <value>trellis_permutation_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>byte</value>
+ </param>
+ <param>
+ <key>interleaver_size</key>
+ <value>interleaver.K()</value>
+ </param>
+ <param>
+ <key>table</key>
+ <value>interleaver.DEINTER()</value>
+ </param>
+ <param>
+ <key>syms_per_block</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(568, 1222)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>trellis_viterbi_combined_xx</key>
+ <param>
+ <key>id</key>
+ <value>trellis_viterbi_combined_xx_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>f</value>
+ </param>
+ <param>
+ <key>out_type</key>
+ <value>b</value>
+ </param>
+ <param>
+ <key>fsm_args</key>
+ <value>fsm_i</value>
+ </param>
+ <param>
+ <key>block_size</key>
+ <value>interleaver.K()</value>
+ </param>
+ <param>
+ <key>init_state</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>final_state</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>dim</key>
+ <value>tot_mod[0]</value>
+ </param>
+ <param>
+ <key>table</key>
+ <value>tot_mod[1]</value>
+ </param>
+ <param>
+ <key>metric_type</key>
+ <value>digital.TRELLIS_EUCLIDEAN</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(288, 1194)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>virtual_sink</key>
+ <param>
+ <key>id</key>
+ <value>virtual_sink_0_1_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>estimate_i</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(896, 1228)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>virtual_source</key>
+ <param>
+ <key>id</key>
+ <value>virtual_source_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>observation</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(40, 1236)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>analog_const_source_x</key>
+ <param>
+ <key>id</key>
+ <value>analog_const_source_x_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>const</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(88, 1788)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>trellis_viterbi_combined_xx</key>
+ <param>
+ <key>id</key>
+ <value>trellis_viterbi_combined_xx_1</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>f</value>
+ </param>
+ <param>
+ <key>out_type</key>
+ <value>b</value>
+ </param>
+ <param>
+ <key>fsm_args</key>
+ <value>fsm_o</value>
+ </param>
+ <param>
+ <key>block_size</key>
+ <value>interleaver.K()</value>
+ </param>
+ <param>
+ <key>init_state</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>final_state</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>dim</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>table</key>
+ <value>0,1,2,3</value>
+ </param>
+ <param>
+ <key>metric_type</key>
+ <value>digital.TRELLIS_HARD_SYMBOL</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(256, 1338)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>trellis_siso_combined_f</key>
+ <param>
+ <key>id</key>
+ <value>trellis_siso_combined_f_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>fsm_args</key>
+ <value>fsm_i</value>
+ </param>
+ <param>
+ <key>block_size</key>
+ <value>interleaver.K()</value>
+ </param>
+ <param>
+ <key>init_state</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>final_state</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>a_post_in</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>a_post_out</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>siso_type</key>
+ <value>trellis.TRELLIS_MIN_SUM</value>
+ </param>
+ <param>
+ <key>dim</key>
+ <value>tot_mod[0]</value>
+ </param>
+ <param>
+ <key>table</key>
+ <value>tot_mod[1]</value>
+ </param>
+ <param>
+ <key>metric_type</key>
+ <value>trellis.TRELLIS_EUCLIDEAN</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(280, 1765)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>trellis_permutation</key>
+ <param>
+ <key>id</key>
+ <value>trellis_permutation_0_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>interleaver_size</key>
+ <value>interleaver.K()</value>
+ </param>
+ <param>
+ <key>table</key>
+ <value>interleaver.DEINTER()</value>
+ </param>
+ <param>
+ <key>syms_per_block</key>
+ <value>fsm_o.O()</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(616, 1814)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>trellis_viterbi_x</key>
+ <param>
+ <key>id</key>
+ <value>trellis_viterbi_x_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>b</value>
+ </param>
+ <param>
+ <key>fsm_args</key>
+ <value>fsm_o</value>
+ </param>
+ <param>
+ <key>block_size</key>
+ <value>interleaver.K()</value>
+ </param>
+ <param>
+ <key>init_state</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>final_state</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(288, 2023)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>virtual_source</key>
+ <param>
+ <key>id</key>
+ <value>virtual_source_0_1</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>observation</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(72, 1860)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>virtual_source</key>
+ <param>
+ <key>id</key>
+ <value>virtual_source_0_1_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>observation</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(88, 2564)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_unpack_k_bits_bb</key>
+ <param>
+ <key>id</key>
+ <value>blocks_unpack_k_bits_bb_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>k</key>
+ <value>bpsym</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(584, 2044)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>virtual_sink</key>
+ <param>
+ <key>id</key>
+ <value>virtual_sink_0_1_1</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>estimate1</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(896, 2044)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>virtual_source</key>
+ <param>
+ <key>id</key>
+ <value>virtual_source_0_0_0_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>estimate1</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(144, 2284)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>virtual_source</key>
+ <param>
+ <key>id</key>
+ <value>virtual_source_0_0_1_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>info</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(152, 2188)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>virtual_source</key>
+ <param>
+ <key>id</key>
+ <value>virtual_source_0_0_1_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>info</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(176, 2732)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>virtual_source</key>
+ <param>
+ <key>id</key>
+ <value>virtual_source_0_0_0_0_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>estimate2</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(168, 2828)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>virtual_source</key>
+ <param>
+ <key>id</key>
+ <value>virtual_source_0_0_1</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>info</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(80, 1556)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>virtual_source</key>
+ <param>
+ <key>id</key>
+ <value>virtual_source_0_0_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>estimate</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(72, 1652)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>wxgui_numbersink2</key>
+ <param>
+ <key>id</key>
+ <value>wxgui_numbersink2_3_0_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value>BER_hard</value>
+ </param>
+ <param>
+ <key>units</key>
+ <value>BER</value>
+ </param>
+ <param>
+ <key>samp_rate</key>
+ <value>R</value>
+ </param>
+ <param>
+ <key>min_value</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>max_value</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>factor</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>decimal_places</key>
+ <value>6</value>
+ </param>
+ <param>
+ <key>ref_level</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>number_rate</key>
+ <value>15</value>
+ </param>
+ <param>
+ <key>peak_hold</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>average</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>avg_alpha</key>
+ <value>0.001</value>
+ </param>
+ <param>
+ <key>show_gauge</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>win_size</key>
+ <value></value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value></value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(504, 1549)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>wxgui_numbersink2</key>
+ <param>
+ <key>id</key>
+ <value>wxgui_numbersink2_3_0_0_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value>BER_soft</value>
+ </param>
+ <param>
+ <key>units</key>
+ <value>BER</value>
+ </param>
+ <param>
+ <key>samp_rate</key>
+ <value>R</value>
+ </param>
+ <param>
+ <key>min_value</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>max_value</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>factor</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>decimal_places</key>
+ <value>6</value>
+ </param>
+ <param>
+ <key>ref_level</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>number_rate</key>
+ <value>15</value>
+ </param>
+ <param>
+ <key>peak_hold</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>average</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>avg_alpha</key>
+ <value>0.001</value>
+ </param>
+ <param>
+ <key>show_gauge</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>win_size</key>
+ <value></value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value></value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(576, 2181)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>wxgui_numbersink2</key>
+ <param>
+ <key>id</key>
+ <value>wxgui_numbersink2_3_0_0_0_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value>BER_turbo</value>
+ </param>
+ <param>
+ <key>units</key>
+ <value>BER</value>
+ </param>
+ <param>
+ <key>samp_rate</key>
+ <value>R</value>
+ </param>
+ <param>
+ <key>min_value</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>max_value</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>factor</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>decimal_places</key>
+ <value>6</value>
+ </param>
+ <param>
+ <key>ref_level</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>number_rate</key>
+ <value>15</value>
+ </param>
+ <param>
+ <key>peak_hold</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>average</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>avg_alpha</key>
+ <value>0.001</value>
+ </param>
+ <param>
+ <key>show_gauge</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>win_size</key>
+ <value></value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value></value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(600, 2725)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>trellis_sccc_decoder_combined_xx</key>
+ <param>
+ <key>id</key>
+ <value>trellis_sccc_decoder_combined_xx_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>f</value>
+ </param>
+ <param>
+ <key>out_type</key>
+ <value>b</value>
+ </param>
+ <param>
+ <key>o_fsm_args</key>
+ <value>fsm_o</value>
+ </param>
+ <param>
+ <key>o_init_state</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>o_final_state</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>i_fsm_args</key>
+ <value>fsm_i</value>
+ </param>
+ <param>
+ <key>i_init_state</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>i_final_state</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>interleaver</key>
+ <value>interleaver</value>
+ </param>
+ <param>
+ <key>block_size</key>
+ <value>interleaver.K()</value>
+ </param>
+ <param>
+ <key>iterations</key>
+ <value>5</value>
+ </param>
+ <param>
+ <key>dim</key>
+ <value>tot_mod[0]</value>
+ </param>
+ <param>
+ <key>table</key>
+ <value>tot_mod[1]</value>
+ </param>
+ <param>
+ <key>metric_type</key>
+ <value>digital.TRELLIS_EUCLIDEAN</value>
+ </param>
+ <param>
+ <key>siso_type</key>
+ <value>trellis.TRELLIS_MIN_SUM</value>
+ </param>
+ <param>
+ <key>scaling</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(456, 2481)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blks2_error_rate</key>
+ <param>
+ <key>id</key>
+ <value>blks2_error_rate_0_0_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>'BER'</value>
+ </param>
+ <param>
+ <key>win_size</key>
+ <value>block_b*100</value>
+ </param>
+ <param>
+ <key>bits_per_symbol</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(408, 2766)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blks2_error_rate</key>
+ <param>
+ <key>id</key>
+ <value>blks2_error_rate_0_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>'BER'</value>
+ </param>
+ <param>
+ <key>win_size</key>
+ <value>block_b*100</value>
+ </param>
+ <param>
+ <key>bits_per_symbol</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(384, 2230)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blks2_error_rate</key>
+ <param>
+ <key>id</key>
+ <value>blks2_error_rate_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>'BER'</value>
+ </param>
+ <param>
+ <key>win_size</key>
+ <value>block_b*100</value>
+ </param>
+ <param>
+ <key>bits_per_symbol</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(312, 1598)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable_slider</key>
+ <param>
+ <key>id</key>
+ <value>EsN0_dB</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>Es/N0 (dB)</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>13.0</value>
+ </param>
+ <param>
+ <key>min</key>
+ <value>-10</value>
+ </param>
+ <param>
+ <key>max</key>
+ <value>30</value>
+ </param>
+ <param>
+ <key>num_steps</key>
+ <value>1000</value>
+ </param>
+ <param>
+ <key>style</key>
+ <value>wx.SL_HORIZONTAL</value>
+ </param>
+ <param>
+ <key>converver</key>
+ <value>float_converter</value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value></value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(936, 129)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_unpack_k_bits_bb</key>
+ <param>
+ <key>id</key>
+ <value>blocks_unpack_k_bits_bb_0_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>k</key>
+ <value>bpsym</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(720, 2572)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>virtual_sink</key>
+ <param>
+ <key>id</key>
+ <value>virtual_sink_0_1_1_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>estimate2</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(920, 2572)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>note</key>
+ <param>
+ <key>id</key>
+ <value>note_0_1</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>note</key>
+ <value>This is the full-fledged turbo equalizer/decoder</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(1144, 2572)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>note</key>
+ <param>
+ <key>id</key>
+ <value>note_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>note</key>
+ <value>This is a better soft-equalizer/Viterbi decoder</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(1016, 1908)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>note</key>
+ <param>
+ <key>id</key>
+ <value>note_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>note</key>
+ <value>This is the simplest hard Viterbi equalizer/hard Viterbi decoder</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(1096, 1316)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <connection>
+ <source_block_id>analog_random_source_x_0</source_block_id>
+ <sink_block_id>virtual_sink_0_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>analog_random_source_x_0</source_block_id>
+ <sink_block_id>blocks_throttle_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>analog_noise_source_x_0</source_block_id>
+ <sink_block_id>blocks_add_xx_1</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>1</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_add_xx_1</source_block_id>
+ <sink_block_id>virtual_sink_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>digital_chunks_to_symbols_xx_0_0</source_block_id>
+ <sink_block_id>fir_filter_xxx_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>fir_filter_xxx_0</source_block_id>
+ <sink_block_id>blocks_add_xx_1</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_throttle_0</source_block_id>
+ <sink_block_id>blocks_pack_k_bits_bb_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_pack_k_bits_bb_0</source_block_id>
+ <sink_block_id>trellis_encoder_xx_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>trellis_encoder_xx_0</source_block_id>
+ <sink_block_id>trellis_permutation_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>trellis_permutation_0</source_block_id>
+ <sink_block_id>digital_chunks_to_symbols_xx_0_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>trellis_encoder_xx_0</source_block_id>
+ <sink_block_id>virtual_sink_0_0_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_char_to_float_0</source_block_id>
+ <sink_block_id>trellis_viterbi_combined_xx_1</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>trellis_permutation_0_0</source_block_id>
+ <sink_block_id>blocks_char_to_float_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>trellis_permutation_0_0</source_block_id>
+ <sink_block_id>virtual_sink_0_1_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_unpack_k_bits_bb_0</source_block_id>
+ <sink_block_id>virtual_sink_0_1</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>trellis_viterbi_combined_xx_1</source_block_id>
+ <sink_block_id>blocks_unpack_k_bits_bb_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>trellis_viterbi_combined_xx_0</source_block_id>
+ <sink_block_id>trellis_permutation_0_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>virtual_source_0</source_block_id>
+ <sink_block_id>trellis_viterbi_combined_xx_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_unpack_k_bits_bb_0_0</source_block_id>
+ <sink_block_id>virtual_sink_0_1_1</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>virtual_source_0_1</source_block_id>
+ <sink_block_id>trellis_siso_combined_f_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>1</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>analog_const_source_x_0</source_block_id>
+ <sink_block_id>trellis_siso_combined_f_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>trellis_siso_combined_f_0</source_block_id>
+ <sink_block_id>trellis_permutation_0_0_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>trellis_permutation_0_0_0</source_block_id>
+ <sink_block_id>trellis_viterbi_x_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>trellis_viterbi_x_0</source_block_id>
+ <sink_block_id>blocks_unpack_k_bits_bb_0_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>virtual_source_0_1_0</source_block_id>
+ <sink_block_id>trellis_sccc_decoder_combined_xx_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_unpack_k_bits_bb_0_0_0</source_block_id>
+ <sink_block_id>virtual_sink_0_1_1_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>trellis_sccc_decoder_combined_xx_0</source_block_id>
+ <sink_block_id>blocks_unpack_k_bits_bb_0_0_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blks2_error_rate_0_0_0</source_block_id>
+ <sink_block_id>wxgui_numbersink2_3_0_0_0_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>virtual_source_0_0_1_0</source_block_id>
+ <sink_block_id>blks2_error_rate_0_0_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>virtual_source_0_0_0_0_0</source_block_id>
+ <sink_block_id>blks2_error_rate_0_0_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>1</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blks2_error_rate_0_0_0_0</source_block_id>
+ <sink_block_id>wxgui_numbersink2_3_0_0_0_0_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>virtual_source_0_0_1_0_0</source_block_id>
+ <sink_block_id>blks2_error_rate_0_0_0_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>virtual_source_0_0_0_0_0_0</source_block_id>
+ <sink_block_id>blks2_error_rate_0_0_0_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>1</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blks2_error_rate_0_0</source_block_id>
+ <sink_block_id>wxgui_numbersink2_3_0_0_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>virtual_source_0_0_1</source_block_id>
+ <sink_block_id>blks2_error_rate_0_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>virtual_source_0_0_0_0</source_block_id>
+ <sink_block_id>blks2_error_rate_0_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>1</sink_key>
+ </connection>
+</flow_graph>
diff --git a/gr-trellis/examples/grc/sccc1.grc b/gr-trellis/examples/grc/viterbi_equalization.grc
index 71b3f76625..2f69ead429 100644
--- a/gr-trellis/examples/grc/sccc1.grc
+++ b/gr-trellis/examples/grc/viterbi_equalization.grc
@@ -1,11 +1,12 @@
<?xml version='1.0' encoding='ASCII'?>
+<?grc format='1' created='3.7.6'?>
<flow_graph>
- <timestamp>Mon Jul 28 14:10:35 2014</timestamp>
+ <timestamp>Wed Oct 1 11:04:18 2014</timestamp>
<block>
<key>options</key>
<param>
<key>id</key>
- <value>sccc1</value>
+ <value>viterbi_equalization</value>
</param>
<param>
<key>_enabled</key>
@@ -13,7 +14,7 @@
</param>
<param>
<key>title</key>
- <value>Serially Concatenated Convolutional Code</value>
+ <value>Viterbi Equalization</value>
</param>
<param>
<key>author</key>
@@ -29,7 +30,7 @@
</param>
<param>
<key>generate_options</key>
- <value>qt_gui</value>
+ <value>wx_gui</value>
</param>
<param>
<key>category</key>
@@ -68,7 +69,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>prefix</value>
+ <value>noisevar</value>
</param>
<param>
<key>_enabled</key>
@@ -76,7 +77,7 @@
</param>
<param>
<key>value</key>
- <value>"@FSM_FILE_INSTALL_DIR@"</value>
+ <value>10**(-EsN0_dB/10.0) * Es /2.0</value>
</param>
<param>
<key>alias</key>
@@ -84,7 +85,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(513, 10)</value>
+ <value>(872, 157)</value>
</param>
<param>
<key>_rotation</key>
@@ -95,7 +96,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>block</value>
+ <value>bpsym</value>
</param>
<param>
<key>_enabled</key>
@@ -103,7 +104,7 @@
</param>
<param>
<key>value</key>
- <value>1000</value>
+ <value>int(round(math.log(fsm.I())/math.log(2)))</value>
</param>
<param>
<key>alias</key>
@@ -111,7 +112,34 @@
</param>
<param>
<key>_coordinate</key>
- <value>(441, 10)</value>
+ <value>(528, 13)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>channel</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>fu.c_channel</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(320, 85)</value>
</param>
<param>
<key>_rotation</key>
@@ -138,7 +166,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(358, 10)</value>
+ <value>(216, 109)</value>
</param>
<param>
<key>_rotation</key>
@@ -149,7 +177,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>noisevar</value>
+ <value>block</value>
</param>
<param>
<key>_enabled</key>
@@ -157,7 +185,7 @@
</param>
<param>
<key>value</key>
- <value>10**(-snr_db/10)</value>
+ <value>bpsym*1000</value>
</param>
<param>
<key>alias</key>
@@ -165,7 +193,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(279, 10)</value>
+ <value>(216, 21)</value>
</param>
<param>
<key>_rotation</key>
@@ -173,54 +201,161 @@
</param>
</block>
<block>
- <key>analog_random_source_x</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>analog_random_source_x_0</value>
+ <value>fsm</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>short</value>
+ <key>value</key>
+ <value>trellis.fsm(len(modulation[1]),len(channel))</value>
</param>
<param>
- <key>min</key>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(320, 157)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>variable</key>
<param>
- <key>max</key>
- <value>2</value>
+ <key>id</key>
+ <value>tot_mod</value>
</param>
<param>
- <key>num_samps</key>
- <value>1000</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>repeat</key>
+ <key>value</key>
+ <value>fu.make_isi_lookup(modulation,channel,False)</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(320, 229)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>modulation</value>
+ </param>
+ <param>
+ <key>_enabled</key>
<value>True</value>
</param>
<param>
+ <key>value</key>
+ <value>fu.pam4</value>
+ </param>
+ <param>
<key>alias</key>
<value></value>
</param>
<param>
- <key>affinity</key>
+ <key>_coordinate</key>
+ <value>(320, 21)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>Es</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>numpy.mean((numpy.square(numpy.abs(tot_mod[1]))))</value>
+ </param>
+ <param>
+ <key>alias</key>
<value></value>
</param>
<param>
- <key>minoutbuf</key>
+ <key>_coordinate</key>
+ <value>(568, 157)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>import</key>
+ <param>
+ <key>id</key>
+ <value>import_0_0</value>
+ </param>
<param>
- <key>maxoutbuf</key>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>import</key>
+ <value>import gnuradio.trellis.fsm_utils as fu</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(24, 252)</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 numpy</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
<param>
<key>_coordinate</key>
- <value>(21, 170)</value>
+ <value>(16, 140)</value>
</param>
<param>
<key>_rotation</key>
@@ -228,32 +363,55 @@
</param>
</block>
<block>
- <key>blocks_throttle</key>
+ <key>import</key>
<param>
<key>id</key>
- <value>blocks_throttle_0</value>
+ <value>import_0_1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>short</value>
+ <key>import</key>
+ <value>import math</value>
</param>
<param>
- <key>samples_per_second</key>
- <value>R</value>
+ <key>alias</key>
+ <value></value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>_coordinate</key>
+ <value>(24, 188)</value>
</param>
<param>
- <key>ignoretag</key>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blks2_error_rate</key>
+ <param>
+ <key>id</key>
+ <value>blks2_error_rate_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
<value>True</value>
</param>
<param>
+ <key>type</key>
+ <value>'BER'</value>
+ </param>
+ <param>
+ <key>win_size</key>
+ <value>block*100</value>
+ </param>
+ <param>
+ <key>bits_per_symbol</key>
+ <value>1</value>
+ </param>
+ <param>
<key>alias</key>
<value></value>
</param>
@@ -271,7 +429,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(607, 110)</value>
+ <value>(312, 1766)</value>
</param>
<param>
<key>_rotation</key>
@@ -279,10 +437,56 @@
</param>
</block>
<block>
- <key>blocks_add_xx</key>
+ <key>virtual_source</key>
<param>
<key>id</key>
- <value>blocks_add_xx_1</value>
+ <value>virtual_source_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>info</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(80, 1724)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>virtual_source</key>
+ <param>
+ <key>id</key>
+ <value>virtual_source_0_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>estimate</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(72, 1820)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>wxgui_numbersink2</key>
+ <param>
+ <key>id</key>
+ <value>wxgui_numbersink2_3_0_0</value>
</param>
<param>
<key>_enabled</key>
@@ -293,12 +497,68 @@
<value>float</value>
</param>
<param>
- <key>num_inputs</key>
- <value>2</value>
+ <key>title</key>
+ <value>BER</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>units</key>
+ <value>BER</value>
+ </param>
+ <param>
+ <key>samp_rate</key>
+ <value>R</value>
+ </param>
+ <param>
+ <key>min_value</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>max_value</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>factor</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>decimal_places</key>
+ <value>6</value>
+ </param>
+ <param>
+ <key>ref_level</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>number_rate</key>
+ <value>15</value>
+ </param>
+ <param>
+ <key>peak_hold</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>average</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>avg_alpha</key>
+ <value>0.001</value>
+ </param>
+ <param>
+ <key>show_gauge</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>win_size</key>
+ <value></value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value></value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
</param>
<param>
<key>alias</key>
@@ -309,16 +569,81 @@
<value></value>
</param>
<param>
- <key>minoutbuf</key>
+ <key>_coordinate</key>
+ <value>(728, 1709)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>note</key>
<param>
- <key>maxoutbuf</key>
+ <key>id</key>
+ <value>note_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>note</key>
+ <value>Substititue the metrics/Viterbi block with Viterbi_combo</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(704, 1468)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_source</key>
+ <param>
+ <key>id</key>
+ <value>virtual_source_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>observation</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(40, 1236)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>virtual_sink</key>
+ <param>
+ <key>id</key>
+ <value>virtual_sink_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>info</value>
+ </param>
<param>
<key>_coordinate</key>
- <value>(932, 187)</value>
+ <value>(232, 524)</value>
</param>
<param>
<key>_rotation</key>
@@ -326,10 +651,10 @@
</param>
</block>
<block>
- <key>blocks_multiply_xx</key>
+ <key>analog_random_source_x</key>
<param>
<key>id</key>
- <value>blocks_multiply_xx_2_0</value>
+ <value>analog_random_source_x_0</value>
</param>
<param>
<key>_enabled</key>
@@ -337,15 +662,23 @@
</param>
<param>
<key>type</key>
- <value>short</value>
+ <value>byte</value>
</param>
<param>
- <key>num_inputs</key>
+ <key>min</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>max</key>
<value>2</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>num_samps</key>
+ <value>1007</value>
+ </param>
+ <param>
+ <key>repeat</key>
+ <value>True</value>
</param>
<param>
<key>alias</key>
@@ -365,7 +698,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(233, 480)</value>
+ <value>(16, 559)</value>
</param>
<param>
<key>_rotation</key>
@@ -373,10 +706,10 @@
</param>
</block>
<block>
- <key>blocks_sub_xx</key>
+ <key>blocks_null_sink</key>
<param>
<key>id</key>
- <value>blocks_sub_xx_0</value>
+ <value>blocks_null_sink_1</value>
</param>
<param>
<key>_enabled</key>
@@ -384,7 +717,7 @@
</param>
<param>
<key>type</key>
- <value>short</value>
+ <value>float</value>
</param>
<param>
<key>vlen</key>
@@ -392,7 +725,11 @@
</param>
<param>
<key>num_inputs</key>
- <value>2</value>
+ <value>1</value>
+ </param>
+ <param>
+ <key>bus_conns</key>
+ <value>[[0,],]</value>
</param>
<param>
<key>alias</key>
@@ -403,16 +740,31 @@
<value></value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
+ <key>_coordinate</key>
+ <value>(800, 1008)</value>
</param>
<param>
- <key>maxoutbuf</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_sink</key>
+ <param>
+ <key>id</key>
+ <value>virtual_sink_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>stream_id</key>
+ <value>observation</value>
+ </param>
<param>
<key>_coordinate</key>
- <value>(58, 486)</value>
+ <value>(608, 1076)</value>
</param>
<param>
<key>_rotation</key>
@@ -420,24 +772,32 @@
</param>
</block>
<block>
- <key>blocks_short_to_float</key>
+ <key>fir_filter_xxx</key>
<param>
<key>id</key>
- <value>blocks_short_to_float_1_0</value>
+ <value>fir_filter_xxx_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>type</key>
+ <value>fff</value>
</param>
<param>
- <key>scale</key>
+ <key>decim</key>
<value>1</value>
</param>
<param>
+ <key>taps</key>
+ <value>fu.c_channel</value>
+ </param>
+ <param>
+ <key>samp_delay</key>
+ <value>0</value>
+ </param>
+ <param>
<key>alias</key>
<value></value>
</param>
@@ -455,7 +815,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(376, 498)</value>
+ <value>(904, 613)</value>
</param>
<param>
<key>_rotation</key>
@@ -463,10 +823,10 @@
</param>
</block>
<block>
- <key>trellis_metrics_x</key>
+ <key>blocks_add_xx</key>
<param>
<key>id</key>
- <value>trellis_metrics_x_0</value>
+ <value>blocks_add_xx_1</value>
</param>
<param>
<key>_enabled</key>
@@ -474,25 +834,17 @@
</param>
<param>
<key>type</key>
- <value>f</value>
+ <value>float</value>
</param>
<param>
- <key>card</key>
- <value>8</value>
+ <key>num_inputs</key>
+ <value>2</value>
</param>
<param>
- <key>dim</key>
+ <key>vlen</key>
<value>1</value>
</param>
<param>
- <key>table</key>
- <value>-7, -5, -3, -1, 1, 3, 5, 7</value>
- </param>
- <param>
- <key>metric_type</key>
- <value>digital.TRELLIS_EUCLIDEAN</value>
- </param>
- <param>
<key>alias</key>
<value></value>
</param>
@@ -510,7 +862,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(63, 328)</value>
+ <value>(688, 944)</value>
</param>
<param>
<key>_rotation</key>
@@ -525,7 +877,7 @@
</param>
<param>
<key>_enabled</key>
- <value>True</value>
+ <value>False</value>
</param>
<param>
<key>in_type</key>
@@ -537,11 +889,11 @@
</param>
<param>
<key>symbol_table</key>
- <value>-7,-5,-3,-1,1,3,5,7</value>
+ <value>tot_mod[1]</value>
</param>
<param>
<key>dimension</key>
- <value>1</value>
+ <value>tot_mod[0]</value>
</param>
<param>
<key>num_ports</key>
@@ -565,7 +917,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(607, 175)</value>
+ <value>(944, 461)</value>
</param>
<param>
<key>_rotation</key>
@@ -592,7 +944,7 @@
</param>
<param>
<key>amp</key>
- <value>noisevar</value>
+ <value>noisevar**0.5</value>
</param>
<param>
<key>seed</key>
@@ -616,7 +968,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(606, 242)</value>
+ <value>(288, 958)</value>
</param>
<param>
<key>_rotation</key>
@@ -624,213 +976,198 @@
</param>
</block>
<block>
- <key>qtgui_number_sink</key>
+ <key>trellis_metrics_x</key>
<param>
<key>id</key>
- <value>qtgui_number_sink_0</value>
+ <value>trellis_metrics_x_0</value>
</param>
<param>
<key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>name</key>
- <value>""</value>
+ <value>False</value>
</param>
<param>
<key>type</key>
- <value>float</value>
- </param>
- <param>
- <key>autoscale</key>
- <value>False</value>
+ <value>f</value>
</param>
<param>
- <key>avg</key>
- <value>0.001</value>
+ <key>card</key>
+ <value>fsm.O()</value>
</param>
<param>
- <key>graph_type</key>
- <value>qtgui.NUM_GRAPH_HORIZ</value>
+ <key>dim</key>
+ <value>tot_mod[0]</value>
</param>
<param>
- <key>nconnections</key>
- <value>1</value>
+ <key>table</key>
+ <value>tot_mod[1]</value>
</param>
<param>
- <key>min</key>
- <value>0</value>
+ <key>metric_type</key>
+ <value>digital.TRELLIS_EUCLIDEAN</value>
</param>
<param>
- <key>max</key>
- <value>1</value>
+ <key>alias</key>
+ <value></value>
</param>
<param>
- <key>update_time</key>
- <value>0.10</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
- <key>gui_hint</key>
- <value>1,0,1,1</value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>label1</key>
- <value></value>
+ <key>maxoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>unit1</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(272, 1271)</value>
</param>
<param>
- <key>color1</key>
- <value>("black", "black")</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>variable_slider</key>
<param>
- <key>factor1</key>
- <value>1</value>
+ <key>id</key>
+ <value>EsN0_dB</value>
</param>
<param>
- <key>label2</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>unit2</key>
- <value></value>
+ <key>label</key>
+ <value>Es/N0 (dB)</value>
</param>
<param>
- <key>color2</key>
- <value>("black", "black")</value>
+ <key>value</key>
+ <value>20.0</value>
</param>
<param>
- <key>factor2</key>
- <value>1</value>
+ <key>min</key>
+ <value>-10</value>
</param>
<param>
- <key>label3</key>
- <value></value>
+ <key>max</key>
+ <value>30</value>
</param>
<param>
- <key>unit3</key>
- <value></value>
+ <key>num_steps</key>
+ <value>1000</value>
</param>
<param>
- <key>color3</key>
- <value>("black", "black")</value>
+ <key>style</key>
+ <value>wx.SL_HORIZONTAL</value>
</param>
<param>
- <key>factor3</key>
- <value>1</value>
+ <key>converver</key>
+ <value>float_converter</value>
</param>
<param>
- <key>label4</key>
+ <key>grid_pos</key>
<value></value>
</param>
<param>
- <key>unit4</key>
+ <key>notebook</key>
<value></value>
</param>
<param>
- <key>color4</key>
- <value>("black", "black")</value>
- </param>
- <param>
- <key>factor4</key>
- <value>1</value>
- </param>
- <param>
- <key>label5</key>
+ <key>alias</key>
<value></value>
</param>
<param>
- <key>unit5</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(728, 105)</value>
</param>
<param>
- <key>color5</key>
- <value>("black", "black")</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>blocks_throttle</key>
<param>
- <key>factor5</key>
- <value>1</value>
+ <key>id</key>
+ <value>blocks_throttle_0</value>
</param>
<param>
- <key>label6</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>unit6</key>
- <value></value>
+ <key>type</key>
+ <value>byte</value>
</param>
<param>
- <key>color6</key>
- <value>("black", "black")</value>
+ <key>samples_per_second</key>
+ <value>R</value>
</param>
<param>
- <key>factor6</key>
+ <key>vlen</key>
<value>1</value>
</param>
<param>
- <key>label7</key>
- <value></value>
+ <key>ignoretag</key>
+ <value>True</value>
</param>
<param>
- <key>unit7</key>
+ <key>alias</key>
<value></value>
</param>
<param>
- <key>color7</key>
- <value>("black", "black")</value>
- </param>
- <param>
- <key>factor7</key>
- <value>1</value>
- </param>
- <param>
- <key>label8</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>unit8</key>
- <value></value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>color8</key>
- <value>("black", "black")</value>
+ <key>maxoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>factor8</key>
- <value>1</value>
+ <key>_coordinate</key>
+ <value>(240, 580)</value>
</param>
<param>
- <key>label9</key>
- <value></value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>digital_chunks_to_symbols_xx</key>
<param>
- <key>unit9</key>
- <value></value>
+ <key>id</key>
+ <value>digital_chunks_to_symbols_xx_0_0</value>
</param>
<param>
- <key>color9</key>
- <value>("black", "black")</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>factor9</key>
- <value>1</value>
+ <key>in_type</key>
+ <value>byte</value>
</param>
<param>
- <key>label10</key>
- <value></value>
+ <key>out_type</key>
+ <value>float</value>
</param>
<param>
- <key>unit10</key>
- <value></value>
+ <key>symbol_table</key>
+ <value>modulation[1]</value>
</param>
<param>
- <key>color10</key>
- <value>("black", "black")</value>
+ <key>dimension</key>
+ <value>modulation[0]</value>
</param>
<param>
- <key>factor10</key>
+ <key>num_ports</key>
<value>1</value>
</param>
<param>
@@ -842,8 +1179,16 @@
<value></value>
</param>
<param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
<key>_coordinate</key>
- <value>(609, 482)</value>
+ <value>(672, 613)</value>
</param>
<param>
<key>_rotation</key>
@@ -851,69 +1196,88 @@
</param>
</block>
<block>
- <key>variable_qtgui_range</key>
+ <key>virtual_sink</key>
<param>
<key>id</key>
- <value>snr_db</value>
+ <value>virtual_sink_0_1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>label</key>
- <value>SNR (dB)</value>
+ <key>stream_id</key>
+ <value>estimate</value>
</param>
<param>
- <key>value</key>
- <value>5</value>
+ <key>_coordinate</key>
+ <value>(944, 1436)</value>
</param>
<param>
- <key>start</key>
- <value>-10</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>trellis_viterbi_x</key>
<param>
- <key>stop</key>
- <value>10</value>
+ <key>id</key>
+ <value>trellis_viterbi_x_0</value>
</param>
<param>
- <key>step</key>
- <value>0.01</value>
+ <key>_enabled</key>
+ <value>False</value>
</param>
<param>
- <key>widget</key>
- <value>counter_slider</value>
+ <key>type</key>
+ <value>b</value>
</param>
<param>
- <key>orient</key>
- <value>Qt.Horizontal</value>
+ <key>fsm_args</key>
+ <value>fsm</value>
</param>
<param>
- <key>min_len</key>
- <value>200</value>
+ <key>block_size</key>
+ <value>block/bpsym</value>
</param>
<param>
- <key>gui_hint</key>
- <value></value>
+ <key>init_state</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>final_state</key>
+ <value>-1</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
<key>_coordinate</key>
- <value>(177, 10)</value>
+ <value>(480, 1271)</value>
</param>
<param>
<key>_rotation</key>
- <value>180</value>
+ <value>0</value>
</param>
</block>
<block>
- <key>trellis_sccc_encoder_xx</key>
+ <key>trellis_viterbi_combined_xx</key>
<param>
<key>id</key>
- <value>trellis_sccc_encoder_xx_0</value>
+ <value>trellis_viterbi_combined_xx_0</value>
</param>
<param>
<key>_enabled</key>
@@ -921,31 +1285,78 @@
</param>
<param>
<key>type</key>
- <value>ss</value>
+ <value>f</value>
</param>
<param>
- <key>o_fsm_args</key>
- <value>prefix+"/awgn1o2_4.fsm"</value>
+ <key>out_type</key>
+ <value>b</value>
</param>
<param>
- <key>o_init_state</key>
+ <key>fsm_args</key>
+ <value>fsm</value>
+ </param>
+ <param>
+ <key>block_size</key>
+ <value>block/bpsym</value>
+ </param>
+ <param>
+ <key>init_state</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>final_state</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>dim</key>
+ <value>tot_mod[0]</value>
+ </param>
+ <param>
+ <key>table</key>
+ <value>tot_mod[1]</value>
+ </param>
+ <param>
+ <key>metric_type</key>
+ <value>digital.TRELLIS_EUCLIDEAN</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>i_fsm_args</key>
- <value>prefix+"/awgn2o3_4.fsm"</value>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(352, 1410)</value>
</param>
<param>
- <key>i_init_state</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>blocks_unpack_k_bits_bb</key>
<param>
- <key>interleaver_args</key>
- <value>trellis.interleaver(block,666)</value>
+ <key>id</key>
+ <value>blocks_unpack_k_bits_bb_0</value>
</param>
<param>
- <key>bl</key>
- <value>block</value>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>k</key>
+ <value>bpsym</value>
</param>
<param>
<key>alias</key>
@@ -965,7 +1376,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(294, 154)</value>
+ <value>(728, 1364)</value>
</param>
<param>
<key>_rotation</key>
@@ -973,58 +1384,65 @@
</param>
</block>
<block>
- <key>trellis_sccc_decoder_x</key>
+ <key>blocks_pack_k_bits_bb</key>
<param>
<key>id</key>
- <value>trellis_sccc_decoder_x_0</value>
+ <value>blocks_pack_k_bits_bb_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>out_type</key>
- <value>s</value>
+ <key>k</key>
+ <value>bpsym</value>
</param>
<param>
- <key>o_fsm_args</key>
- <value>prefix+"/awgn1o2_4.fsm"</value>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
- <key>o_init_state</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>o_final_state</key>
- <value>-1</value>
+ <key>maxoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>i_fsm_args</key>
- <value>prefix+"/awgn2o3_4.fsm"</value>
+ <key>_coordinate</key>
+ <value>(456, 572)</value>
</param>
<param>
- <key>i_init_state</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>trellis_encoder_xx</key>
<param>
- <key>i_final_state</key>
- <value>-1</value>
+ <key>id</key>
+ <value>trellis_encoder_xx_0</value>
</param>
<param>
- <key>interleaver</key>
- <value>trellis.interleaver(block,666)</value>
+ <key>_enabled</key>
+ <value>False</value>
</param>
<param>
- <key>block_size</key>
- <value>block</value>
+ <key>type</key>
+ <value>bs</value>
</param>
<param>
- <key>iterations</key>
- <value>10</value>
+ <key>fsm_args</key>
+ <value>fsm</value>
</param>
<param>
- <key>siso_type</key>
- <value>trellis.TRELLIS_MIN_SUM</value>
+ <key>init_state</key>
+ <value>0</value>
</param>
<param>
<key>alias</key>
@@ -1044,7 +1462,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(292, 280)</value>
+ <value>(672, 461)</value>
</param>
<param>
<key>_rotation</key>
@@ -1052,44 +1470,80 @@
</param>
</block>
<connection>
- <source_block_id>analog_random_source_x_0</source_block_id>
- <sink_block_id>blocks_sub_xx_0</sink_block_id>
+ <source_block_id>blks2_error_rate_0</source_block_id>
+ <sink_block_id>wxgui_numbersink2_3_0_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>virtual_source_0_0</source_block_id>
+ <sink_block_id>blks2_error_rate_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>virtual_source_0_0_0</source_block_id>
+ <sink_block_id>blks2_error_rate_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>1</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>virtual_source_0</source_block_id>
+ <sink_block_id>trellis_metrics_x_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>trellis_metrics_x_0</source_block_id>
+ <sink_block_id>trellis_viterbi_x_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>virtual_source_0</source_block_id>
+ <sink_block_id>trellis_viterbi_combined_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>analog_random_source_x_0</source_block_id>
- <sink_block_id>trellis_sccc_encoder_xx_0</sink_block_id>
+ <sink_block_id>virtual_sink_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>trellis_sccc_encoder_xx_0</source_block_id>
+ <source_block_id>analog_random_source_x_0</source_block_id>
<sink_block_id>blocks_throttle_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
+ <source_block_id>analog_noise_source_x_0</source_block_id>
+ <sink_block_id>blocks_add_xx_1</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>1</sink_key>
+ </connection>
+ <connection>
<source_block_id>blocks_add_xx_1</source_block_id>
- <sink_block_id>trellis_metrics_x_0</sink_block_id>
+ <sink_block_id>blocks_null_sink_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>trellis_metrics_x_0</source_block_id>
- <sink_block_id>trellis_sccc_decoder_x_0</sink_block_id>
+ <source_block_id>blocks_add_xx_1</source_block_id>
+ <sink_block_id>virtual_sink_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>trellis_sccc_decoder_x_0</source_block_id>
- <sink_block_id>blocks_sub_xx_0</sink_block_id>
+ <source_block_id>digital_chunks_to_symbols_xx_0_0</source_block_id>
+ <sink_block_id>fir_filter_xxx_0</sink_block_id>
<source_key>0</source_key>
- <sink_key>1</sink_key>
+ <sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_throttle_0</source_block_id>
- <sink_block_id>digital_chunks_to_symbols_xx_0</sink_block_id>
+ <source_block_id>fir_filter_xxx_0</source_block_id>
+ <sink_block_id>blocks_add_xx_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
@@ -1100,32 +1554,44 @@
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>analog_noise_source_x_0</source_block_id>
- <sink_block_id>blocks_add_xx_1</sink_block_id>
+ <source_block_id>trellis_encoder_xx_0</source_block_id>
+ <sink_block_id>digital_chunks_to_symbols_xx_0</sink_block_id>
<source_key>0</source_key>
- <sink_key>1</sink_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_throttle_0</source_block_id>
+ <sink_block_id>blocks_pack_k_bits_bb_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_sub_xx_0</source_block_id>
- <sink_block_id>blocks_multiply_xx_2_0</sink_block_id>
+ <source_block_id>blocks_pack_k_bits_bb_0</source_block_id>
+ <sink_block_id>digital_chunks_to_symbols_xx_0_0</sink_block_id>
<source_key>0</source_key>
- <sink_key>1</sink_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_unpack_k_bits_bb_0</source_block_id>
+ <sink_block_id>virtual_sink_0_1</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_sub_xx_0</source_block_id>
- <sink_block_id>blocks_multiply_xx_2_0</sink_block_id>
+ <source_block_id>trellis_viterbi_x_0</source_block_id>
+ <sink_block_id>blocks_unpack_k_bits_bb_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_multiply_xx_2_0</source_block_id>
- <sink_block_id>blocks_short_to_float_1_0</sink_block_id>
+ <source_block_id>trellis_viterbi_combined_xx_0</source_block_id>
+ <sink_block_id>blocks_unpack_k_bits_bb_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_short_to_float_1_0</source_block_id>
- <sink_block_id>qtgui_number_sink_0</sink_block_id>
+ <source_block_id>blocks_pack_k_bits_bb_0</source_block_id>
+ <sink_block_id>trellis_encoder_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
diff --git a/gr-trellis/examples/python/CMakeLists.txt b/gr-trellis/examples/python/CMakeLists.txt
index e2c7e70ff7..8a05525bc4 100644
--- a/gr-trellis/examples/python/CMakeLists.txt
+++ b/gr-trellis/examples/python/CMakeLists.txt
@@ -21,18 +21,8 @@ include(GrPython)
GR_PYTHON_INSTALL(
PROGRAMS
- fsm_utils.py
test_tcm.py
- test_tcm_parallel.py
- test_tcm_combined.py
- test_sccc_hard.py
- test_sccc_soft.py
- test_sccc_turbo.py
- test_viterbi_equalization1.py
- test_viterbi_equalization.py
- test_turbo_equalization.py
- test_turbo_equalization1.py
- test_turbo_equalization2.py
+ test_cpm.py
DESTINATION ${GR_PKG_TRELLIS_EXAMPLES_DIR}
COMPONENT "trellis_examples"
)
@@ -45,20 +35,38 @@ install(
install(
FILES
+ fsm_files/awgn1o1_16rsc.fsm
+ fsm_files/awgn1o1_4rsc.fsm
fsm_files/awgn1o2_128.fsm
fsm_files/awgn1o2_16.fsm
+ fsm_files/awgn1o2_16rsc.fsm
fsm_files/awgn1o2_4.fsm
+ fsm_files/awgn1o2_4rsc.fsm
fsm_files/awgn1o2_8.fsm
fsm_files/awgn2o3_16.fsm
+ fsm_files/awgn2o3_16ungerboecka.fsm
+ fsm_files/awgn2o3_16ungerboeck.fsm
+ fsm_files/awgn2o3_32ungerboecka.fsm
+ fsm_files/awgn2o3_32ungerboeck.fsm
fsm_files/awgn2o3_4.fsm
fsm_files/awgn2o3_4_msb.fsm
fsm_files/awgn2o3_4_msbG.fsm
+ fsm_files/awgn2o3_4ungerboecka.fsm
+ fsm_files/awgn2o3_4ungerboeck.fsm
+ fsm_files/awgn2o3_64ungerboecka.fsm
+ fsm_files/awgn2o3_64ungerboeck.fsm
fsm_files/awgn2o3_8.fsm
+ fsm_files/awgn2o3_8ungerboecka.fsm
+ fsm_files/awgn2o3_8ungerboeck.fsm
fsm_files/awgn2o4_4.fsm
fsm_files/disconnected.fsm
+ fsm_files/irregular.fsm
+ fsm_files/joint_16_16.fsm
+ fsm_files/joint_4_16.fsm
fsm_files/rep3.fsm
fsm_files/rep5.fsm
fsm_files/simple.fsm
+ fsm_files/uncoded4.fsm
DESTINATION ${GR_PKG_TRELLIS_EXAMPLES_DIR}/fsm_files
COMPONENT "trellis_examples"
)
diff --git a/gr-trellis/examples/python/README b/gr-trellis/examples/python/README
index 155b0a9416..8b4e0f0abb 100644
--- a/gr-trellis/examples/python/README
+++ b/gr-trellis/examples/python/README
@@ -2,8 +2,6 @@ Here we have several test programs for use with the gr-trellis implementation.
Documentation can be found in
http://gnuradio.org/doc/doxygen/group__trellis__coding__blk.html
-fsm_utils.py contains several useful functions.
-
fsm_files is a directory with some FSM definitions
If you just want to see what these programs do run them;
@@ -26,10 +24,12 @@ which gives you information about the:
number of transmitted packets
number of packets in error
estimated packet error rate
-number of transmitted shorts (or symbols, or bits, depending on the specific program)
-number of shorts (or symbols, or bits) in error
-estimated short (or symbol, or bit) error rate
+number of transmitted symbols, or bits, depending on the specific program
+number of symbols, or bits in error
+estimated symbol, or bit error rate
for instance, the final number 1.10e-03 is the error rate estimate by sending 1000
packets of 1024 shorts each, using an 1/2 4-state convolutional code
and QPSK modulation through an AWGN with Es/N0 = 6.0 dB
+
+There is a similar example in the ../grc/ directory
diff --git a/gr-trellis/examples/python/fsm_files/awgn1o1_16rsc.fsm b/gr-trellis/examples/python/fsm_files/awgn1o1_16rsc.fsm
new file mode 100644
index 0000000000..f82d6052c2
--- /dev/null
+++ b/gr-trellis/examples/python/fsm_files/awgn1o1_16rsc.fsm
@@ -0,0 +1,40 @@
+2 16 2
+
+0 8
+8 0
+1 9
+9 1
+2 10
+10 2
+3 11
+11 3
+12 4
+4 12
+13 5
+5 13
+14 6
+6 14
+15 7
+7 15
+
+
+0 1
+0 1
+1 0
+1 0
+1 0
+1 0
+0 1
+0 1
+1 0
+1 0
+0 1
+0 1
+0 1
+0 1
+1 0
+1 0
+
+Recursive Systematic Codes(RSC)
+GM1o2_16rsc=[1, 1+D+D^4/1+D^2+D^3+D^4] = [1, 27/31] (in decimal);
+
diff --git a/gr-trellis/examples/python/fsm_files/awgn1o1_4rsc.fsm b/gr-trellis/examples/python/fsm_files/awgn1o1_4rsc.fsm
new file mode 100644
index 0000000000..d5e7fe31ba
--- /dev/null
+++ b/gr-trellis/examples/python/fsm_files/awgn1o1_4rsc.fsm
@@ -0,0 +1,16 @@
+2 4 2
+
+0 2
+2 0
+1 3
+3 1
+
+0 1
+0 1
+1 0
+1 0
+
+
+Recursive Systematic Codes(RSC)
+GM1o2_4rsc=[1, 1+D+D^2/1+D^2] = [1, 7/5] (in decimal);
+without the systematic bit
diff --git a/gr-trellis/examples/python/fsm_files/awgn1o2_16rsc.fsm b/gr-trellis/examples/python/fsm_files/awgn1o2_16rsc.fsm
new file mode 100644
index 0000000000..ccf1f1d4b1
--- /dev/null
+++ b/gr-trellis/examples/python/fsm_files/awgn1o2_16rsc.fsm
@@ -0,0 +1,40 @@
+2 16 4
+
+0 8
+8 0
+1 9
+9 1
+2 10
+10 2
+3 11
+11 3
+12 4
+4 12
+13 5
+5 13
+14 6
+6 14
+15 7
+7 15
+
+
+0 3
+0 3
+1 2
+1 2
+1 2
+1 2
+0 3
+0 3
+1 2
+1 2
+0 3
+0 3
+0 3
+0 3
+1 2
+1 2
+
+Recursive Systematic Codes(RSC)
+GM1o2_16rsc=[1, 1+D+D^4/1+D^2+D^3+D^4] = [1, 27/31] (in decimal);
+
diff --git a/gr-trellis/examples/python/fsm_files/awgn1o2_4rsc.fsm b/gr-trellis/examples/python/fsm_files/awgn1o2_4rsc.fsm
new file mode 100644
index 0000000000..adb500a217
--- /dev/null
+++ b/gr-trellis/examples/python/fsm_files/awgn1o2_4rsc.fsm
@@ -0,0 +1,14 @@
+2 4 4
+
+0 2
+2 0
+1 3
+3 1
+
+0 3
+0 3
+1 2
+1 2
+
+Recursive Systematic Codes(RSC)
+GM1o2_4rsc=[1, 1+D+D^2/1+D^2] = [1, 7/5] (in decimal);
diff --git a/gr-trellis/examples/python/fsm_files/awgn2o3_16ungerboeck.fsm b/gr-trellis/examples/python/fsm_files/awgn2o3_16ungerboeck.fsm
new file mode 100644
index 0000000000..70ead4f17a
--- /dev/null
+++ b/gr-trellis/examples/python/fsm_files/awgn2o3_16ungerboeck.fsm
@@ -0,0 +1,50 @@
+4 16 8
+
+0 1 2 3
+4 5 6 7
+8 9 10 11
+12 13 14 15
+0 1 2 3
+4 5 6 7
+8 9 10 11
+12 13 14 15
+0 1 2 3
+4 5 6 7
+8 9 10 11
+12 13 14 15
+0 1 2 3
+4 5 6 7
+8 9 10 11
+12 13 14 15
+
+
+0 4 2 6
+1 5 3 7
+4 0 6 2
+5 1 7 3
+2 6 0 4
+3 7 1 5
+6 2 4 0
+7 3 5 1
+4 0 6 2
+5 1 7 3
+0 4 2 6
+1 5 3 7
+6 2 4 0
+7 3 5 1
+2 6 0 4
+3 7 1 5
+
+This is the rate 2/3 Ungerboeck code with 16 states for 8-PSK (natural mapping).
+The states are defined in Ungerboeck's way.
+
+d_free^2 = 2.274^2 Es --> 7.13 dB (so gain of 4.13 dB over uncoded QPSK)
+
+Parity check matrix in octal: [16 04 23]
+
+Generator Matrix:
+
+[ D 1+D+D^2 0
+ 1+D^2 D^2 D]
+
+
diff --git a/gr-trellis/examples/python/fsm_files/awgn2o3_16ungerboecka.fsm b/gr-trellis/examples/python/fsm_files/awgn2o3_16ungerboecka.fsm
new file mode 100644
index 0000000000..523384362f
--- /dev/null
+++ b/gr-trellis/examples/python/fsm_files/awgn2o3_16ungerboecka.fsm
@@ -0,0 +1,48 @@
+4 16 8
+
+0 8 2 10
+0 8 2 10
+1 9 3 11
+1 9 3 11
+0 8 2 10
+0 8 2 10
+1 9 3 11
+1 9 3 11
+4 12 6 14
+4 12 6 14
+5 13 7 15
+5 13 7 15
+4 12 6 14
+4 12 6 14
+5 13 7 15
+5 13 7 15
+
+
+0 6 2 4
+2 4 0 6
+6 0 4 2
+4 2 6 0
+4 2 6 0
+6 0 4 2
+2 4 0 6
+0 6 2 4
+1 7 3 5
+3 5 1 7
+7 1 5 3
+5 3 7 1
+5 3 7 1
+7 1 5 3
+3 5 1 7
+1 7 3 5
+
+This is the rate 2/3 Ungerboeck code with 16 states for 8-PSK (natural mapping).
+The states are defined in typical way.
+
+d_free^2 = 2.274^2Es --> 7.13 dB (so gain of 4.13 dB over uncoded QPSK)
+
+Parity check matrix in octal: [16 04 23]
+
+Generator Matrix:
+
+[ D 1+D+D^2 0
+ 1+D^2 D^2 D]
diff --git a/gr-trellis/examples/python/fsm_files/awgn2o3_32ungerboeck.fsm b/gr-trellis/examples/python/fsm_files/awgn2o3_32ungerboeck.fsm
new file mode 100644
index 0000000000..a00f9c2e8d
--- /dev/null
+++ b/gr-trellis/examples/python/fsm_files/awgn2o3_32ungerboeck.fsm
@@ -0,0 +1,83 @@
+4 32 8
+
+0 16 1 17
+0 16 1 17
+0 16 1 17
+0 16 1 17
+2 18 3 19
+2 18 3 19
+2 18 3 19
+2 18 3 19
+4 20 5 21
+4 20 5 21
+4 20 5 21
+4 20 5 21
+6 22 7 23
+6 22 7 23
+6 22 7 23
+6 22 7 23
+8 24 9 25
+8 24 9 25
+8 24 9 25
+8 24 9 25
+10 26 11 27
+10 26 11 27
+10 26 11 27
+10 26 11 27
+12 28 13 29
+12 28 13 29
+12 28 13 29
+12 28 13 29
+14 30 15 31
+14 30 15 31
+14 30 15 31
+14 30 15 31
+
+
+
+
+0 4 2 6
+4 0 6 2
+2 6 0 4
+6 2 4 0
+5 1 7 3
+1 5 3 7
+7 3 5 1
+3 7 1 5
+1 5 3 7
+5 1 7 3
+3 7 1 5
+7 3 5 1
+4 0 6 2
+0 4 2 6
+6 2 4 0
+2 6 0 4
+1 5 3 7
+5 1 7 3
+3 7 1 5
+7 3 5 1
+4 0 6 2
+0 4 2 6
+6 2 4 0
+2 6 0 4
+0 4 2 6
+4 0 6 2
+2 6 0 4
+6 2 4 0
+5 1 7 3
+1 5 3 7
+7 3 5 1
+3 7 1 5
+
+This is the rate 2/3 Ungerboeck code with 32 states for 8-PSK (natural mapping).
+The states are defined in typical way.
+
+d_free^2 = 2.405^2 Es --> 7.59 dB (so gain of 4.59 dB over uncoded QPSK)
+
+Parity check matrix in octal: [34 16 45]
+
+Generator Matrix:
+
+[ 1 D 0
+ D^4 D^2+1 D^3+D^2+D]
+
diff --git a/gr-trellis/examples/python/fsm_files/awgn2o3_32ungerboecka.fsm b/gr-trellis/examples/python/fsm_files/awgn2o3_32ungerboecka.fsm
new file mode 100644
index 0000000000..b2e6ebdf44
--- /dev/null
+++ b/gr-trellis/examples/python/fsm_files/awgn2o3_32ungerboecka.fsm
@@ -0,0 +1,84 @@
+4 32 8
+0 16 1 17
+0 16 1 17
+0 16 1 17
+0 16 1 17
+2 18 3 19
+2 18 3 19
+2 18 3 19
+2 18 3 19
+4 20 5 21
+4 20 5 21
+4 20 5 21
+4 20 5 21
+6 22 7 23
+6 22 7 23
+6 22 7 23
+6 22 7 23
+8 24 9 25
+8 24 9 25
+8 24 9 25
+8 24 9 25
+10 26 11 27
+10 26 11 27
+10 26 11 27
+10 26 11 27
+12 28 13 29
+12 28 13 29
+12 28 13 29
+12 28 13 29
+14 30 15 31
+14 30 15 31
+14 30 15 31
+14 30 15 31
+
+
+
+
+
+0 4 2 6
+4 0 6 2
+2 6 0 4
+6 2 4 0
+1 5 3 7
+5 1 7 3
+3 7 1 5
+7 3 5 1
+3 7 1 5
+7 3 5 1
+1 5 3 7
+5 1 7 3
+2 6 0 4
+6 2 4 0
+0 4 2 6
+4 0 6 2
+1 5 3 7
+5 1 7 3
+3 7 1 5
+7 3 5 1
+0 4 2 6
+4 0 6 2
+2 6 0 4
+6 2 4 0
+2 6 0 4
+6 2 4 0
+0 4 2 6
+4 0 6 2
+3 7 1 5
+7 3 5 1
+1 5 3 7
+5 1 7 3
+
+This is the rate 2/3 Ungerboeck code with 32 states for 8-PSK (natural mapping).
+The states are defined in typical way.
+
+d_free^2 = 2.405^2 Es --> 7.59 dB (so gain of 4.59 dB over uncoded QPSK)
+
+Parity check matrix in octal: [34 16 45]
+
+Generator Matrix:
+
+[ 1 D 0
+ D^4+D 1 D^3+D^2+D]
+
+
diff --git a/gr-trellis/examples/python/fsm_files/awgn2o3_4_msb.fsm b/gr-trellis/examples/python/fsm_files/awgn2o3_4_msb.fsm
index d834c52718..ff6e2a763b 100644
--- a/gr-trellis/examples/python/fsm_files/awgn2o3_4_msb.fsm
+++ b/gr-trellis/examples/python/fsm_files/awgn2o3_4_msb.fsm
@@ -12,7 +12,7 @@
This is generated by the 1/2 AWGN code (5 7) operated twice, ie,
-(xk+1 xki) [xk-1 xk-2] -> [xk+1 xki].
+(xk+1 xk) [xk-1 xk-2] -> [xk+1 xk].
We also puncture the first (MSB) bit.
This code is worse than awgn2o3_4_msbG and slightly worse than
awgn2o3_4, BUT seems to be a good innner code for sctcm (with 8PSK natural).
diff --git a/gr-trellis/examples/python/fsm_files/awgn2o3_4_msbG.fsm b/gr-trellis/examples/python/fsm_files/awgn2o3_4_msbG.fsm
index 8956c53da2..54f9cbc3cc 100644
--- a/gr-trellis/examples/python/fsm_files/awgn2o3_4_msbG.fsm
+++ b/gr-trellis/examples/python/fsm_files/awgn2o3_4_msbG.fsm
@@ -11,7 +11,7 @@
This is generated by the 1/2 AWGN code (5 7) operated twice, ie,
-(xk+1 xki) [xk-1 xk-2] -> [xk+1 xki].
+(xk+1 xk) [xk-1 xk-2] -> [xk+1 xk].
We also puncture the first (MSB) bit and Gray map the symbols.
intermediate states:
@@ -45,7 +45,7 @@ and in decimal:
After Gray mapping:
label -> phase
0 -> 0
-1 -> 0
+1 -> 1
2 -> 7
3 -> 2
4 -> 5
diff --git a/gr-trellis/examples/python/fsm_files/awgn2o3_4ungerboeck.fsm b/gr-trellis/examples/python/fsm_files/awgn2o3_4ungerboeck.fsm
new file mode 100644
index 0000000000..160f4ea30f
--- /dev/null
+++ b/gr-trellis/examples/python/fsm_files/awgn2o3_4ungerboeck.fsm
@@ -0,0 +1,26 @@
+4 4 8
+
+0 0 1 1
+2 2 3 3
+0 0 1 1
+2 2 3 3
+
+
+0 4 2 6
+1 5 3 7
+2 6 0 4
+3 7 1 5
+
+
+
+This is the Ungerboeck code for 8-PSK (natural mapping).
+The states are defined in Ungerboeck's way.
+
+d_free^2=4 Es -> 3.0 dB over uncoded QPSK
+
+Parity check matrix in octal: [0 2 5]
+
+Generator matrix:
+
+[1 0 0
+ 0 1+D^2 D]
diff --git a/gr-trellis/examples/python/fsm_files/awgn2o3_4ungerboecka.fsm b/gr-trellis/examples/python/fsm_files/awgn2o3_4ungerboecka.fsm
new file mode 100644
index 0000000000..d9c210a0e9
--- /dev/null
+++ b/gr-trellis/examples/python/fsm_files/awgn2o3_4ungerboecka.fsm
@@ -0,0 +1,23 @@
+4 4 8
+
+0 2 0 2
+0 2 0 2
+1 3 1 3
+1 3 1 3
+
+0 2 4 6
+2 0 6 4
+1 3 5 7
+3 1 7 5
+
+This is the rate 2/3 Ungerboeck's code with 4 states.
+The states are defined in typical way.
+
+d_free^2=4 Es -> 3.0 dB over uncoded QPSK
+
+Parity check matrix in octal: [0 2 5]
+
+Generator matrix:
+
+[1 0 0
+ 0 1+D^2 D]
diff --git a/gr-trellis/examples/python/fsm_files/awgn2o3_64ungerboeck.fsm b/gr-trellis/examples/python/fsm_files/awgn2o3_64ungerboeck.fsm
new file mode 100644
index 0000000000..62c75c31c1
--- /dev/null
+++ b/gr-trellis/examples/python/fsm_files/awgn2o3_64ungerboeck.fsm
@@ -0,0 +1,150 @@
+4 64 8
+
+
+0 32 1 33
+0 32 1 33
+0 32 1 33
+0 32 1 33
+2 34 3 35
+2 34 3 35
+2 34 3 35
+2 34 3 35
+4 36 5 37
+4 36 5 37
+4 36 5 37
+4 36 5 37
+6 38 7 39
+6 38 7 39
+6 38 7 39
+6 38 7 39
+8 40 9 41
+8 40 9 41
+8 40 9 41
+8 40 9 41
+10 42 11 43
+10 42 11 43
+10 42 11 43
+10 42 11 43
+12 44 13 45
+12 44 13 45
+12 44 13 45
+12 44 13 45
+14 46 15 47
+14 46 15 47
+14 46 15 47
+14 46 15 47
+16 48 17 49
+16 48 17 49
+16 48 17 49
+16 48 17 49
+18 50 19 51
+18 50 19 51
+18 50 19 51
+18 50 19 51
+20 52 21 53
+20 52 21 53
+20 52 21 53
+20 52 21 53
+22 54 23 55
+22 54 23 55
+22 54 23 55
+22 54 23 55
+24 56 25 57
+24 56 25 57
+24 56 25 57
+24 56 25 57
+26 58 27 59
+26 58 27 59
+26 58 27 59
+26 58 27 59
+28 60 29 61
+28 60 29 61
+28 60 29 61
+28 60 29 61
+30 62 31 63
+30 62 31 63
+30 62 31 63
+30 62 31 63
+
+
+
+
+0 4 2 6
+4 0 6 2
+2 6 0 4
+6 2 4 0
+1 5 3 7
+5 1 7 3
+3 7 1 5
+7 3 5 1
+3 7 1 5
+7 3 5 1
+1 5 3 7
+5 1 7 3
+2 6 0 4
+6 2 4 0
+0 4 2 6
+4 0 6 2
+1 5 3 7
+5 1 7 3
+3 7 1 5
+7 3 5 1
+0 4 2 6
+4 0 6 2
+2 6 0 4
+6 2 4 0
+2 6 0 4
+6 2 4 0
+0 4 2 6
+4 0 6 2
+3 7 1 5
+7 3 5 1
+1 5 3 7
+5 1 7 3
+1 5 3 7
+5 1 7 3
+3 7 1 5
+7 3 5 1
+0 4 2 6
+4 0 6 2
+2 6 0 4
+6 2 4 0
+2 6 0 4
+6 2 4 0
+0 4 2 6
+4 0 6 2
+3 7 1 5
+7 3 5 1
+1 5 3 7
+5 1 7 3
+0 4 2 6
+4 0 6 2
+2 6 0 4
+6 2 4 0
+1 5 3 7
+5 1 7 3
+3 7 1 5
+7 3 5 1
+3 7 1 5
+7 3 5 1
+1 5 3 7
+5 1 7 3
+2 6 0 4
+6 2 4 0
+0 4 2 6
+4 0 6 2
+
+
+This is the rate 2/3 Ungerboeck code with 64 states for 8-PSK (natural mapping).
+The states are defined in typical way.
+
+d_free^2 = 2.52^2 Es --> 8.01 dB (so gain of 5.01 dB over uncoded QPSK)
+
+parity check matrix in octal: [074 036 105]
+
+generator matrix:
+
+[1 D 0
+ D^5 D^2+1 D^4+D^3+D^2+D]
+
+
diff --git a/gr-trellis/examples/python/fsm_files/awgn2o3_64ungerboecka.fsm b/gr-trellis/examples/python/fsm_files/awgn2o3_64ungerboecka.fsm
new file mode 100644
index 0000000000..137091f1f6
--- /dev/null
+++ b/gr-trellis/examples/python/fsm_files/awgn2o3_64ungerboecka.fsm
@@ -0,0 +1,154 @@
+4 64 8
+
+
+0 32 1 33
+0 32 1 33
+0 32 1 33
+0 32 1 33
+2 34 3 35
+2 34 3 35
+2 34 3 35
+2 34 3 35
+4 36 5 37
+4 36 5 37
+4 36 5 37
+4 36 5 37
+6 38 7 39
+6 38 7 39
+6 38 7 39
+6 38 7 39
+8 40 9 41
+8 40 9 41
+8 40 9 41
+8 40 9 41
+10 42 11 43
+10 42 11 43
+10 42 11 43
+10 42 11 43
+12 44 13 45
+12 44 13 45
+12 44 13 45
+12 44 13 45
+14 46 15 47
+14 46 15 47
+14 46 15 47
+14 46 15 47
+16 48 17 49
+16 48 17 49
+16 48 17 49
+16 48 17 49
+18 50 19 51
+18 50 19 51
+18 50 19 51
+18 50 19 51
+20 52 21 53
+20 52 21 53
+20 52 21 53
+20 52 21 53
+22 54 23 55
+22 54 23 55
+22 54 23 55
+22 54 23 55
+24 56 25 57
+24 56 25 57
+24 56 25 57
+24 56 25 57
+26 58 27 59
+26 58 27 59
+26 58 27 59
+26 58 27 59
+28 60 29 61
+28 60 29 61
+28 60 29 61
+28 60 29 61
+30 62 31 63
+30 62 31 63
+30 62 31 63
+30 62 31 63
+
+
+
+
+
+0 4 2 6
+4 0 6 2
+2 6 0 4
+6 2 4 0
+5 1 7 3
+1 5 3 7
+7 3 5 1
+3 7 1 5
+1 5 3 7
+5 1 7 3
+3 7 1 5
+7 3 5 1
+4 0 6 2
+0 4 2 6
+6 2 4 0
+2 6 0 4
+1 5 3 7
+5 1 7 3
+3 7 1 5
+7 3 5 1
+4 0 6 2
+0 4 2 6
+6 2 4 0
+2 6 0 4
+0 4 2 6
+4 0 6 2
+2 6 0 4
+6 2 4 0
+5 1 7 3
+1 5 3 7
+7 3 5 1
+3 7 1 5
+1 5 3 7
+5 1 7 3
+3 7 1 5
+7 3 5 1
+4 0 6 2
+0 4 2 6
+6 2 4 0
+2 6 0 4
+0 4 2 6
+4 0 6 2
+2 6 0 4
+6 2 4 0
+5 1 7 3
+1 5 3 7
+7 3 5 1
+3 7 1 5
+0 4 2 6
+4 0 6 2
+2 6 0 4
+6 2 4 0
+5 1 7 3
+1 5 3 7
+7 3 5 1
+3 7 1 5
+1 5 3 7
+5 1 7 3
+3 7 1 5
+7 3 5 1
+4 0 6 2
+0 4 2 6
+6 2 4 0
+2 6 0 4
+
+
+
+
+
+This is the rate 2/3 Ungerboeck code with 64 states for 8-PSK (natural mapping).
+The states are defined in typical way.
+
+d_free^2 = 2.52^2 Es --> 8.01 dB (so gain of 5.01 dB over uncoded QPSK)
+
+parity check matrix in octal: [074 036 105]
+
+generator matrix:
+
+[1 D 0
+ D^5+D 1 D^4+D^3+D^2+D]
+
+
diff --git a/gr-trellis/examples/python/fsm_files/awgn2o3_8.fsm b/gr-trellis/examples/python/fsm_files/awgn2o3_8.fsm
index 34deeb68cb..6ace4f5e14 100644
--- a/gr-trellis/examples/python/fsm_files/awgn2o3_8.fsm
+++ b/gr-trellis/examples/python/fsm_files/awgn2o3_8.fsm
@@ -21,5 +21,6 @@
-This is generated by the 1/2 8-state AWGN code (15 17) by puncturing the fourth bit.
+This is generated by the 1/2 8-state AWGN code (15 17) by operating it twice and
+puncturing the fourth bit.
--> d_free=???
diff --git a/gr-trellis/examples/python/fsm_files/awgn2o3_8ungerboeck.fsm b/gr-trellis/examples/python/fsm_files/awgn2o3_8ungerboeck.fsm
new file mode 100644
index 0000000000..e2f08eba25
--- /dev/null
+++ b/gr-trellis/examples/python/fsm_files/awgn2o3_8ungerboeck.fsm
@@ -0,0 +1,35 @@
+4 8 8
+
+0 1 2 3
+4 5 6 7
+0 1 2 3
+4 5 6 7
+0 1 2 3
+4 5 6 7
+0 1 2 3
+4 5 6 7
+
+
+0 4 2 6
+1 5 3 7
+4 0 6 2
+5 1 7 3
+2 6 0 4
+3 7 1 5
+6 2 4 0
+7 3 5 1
+
+
+
+This is the rate 2/3 Ungerboeck code with 8-states for 8-PSK (natural mapping).
+The states are defined in Ungerboeck's way.
+
+d_free^2 = 4.585 Es --> 6.6 dB (so gain of 3.6 dB over uncoded QPSK)
+
+Parity check matrix in octal: [04 02 11]
+
+Generator Matrix:
+
+[ 1 D 0
+ D^2 1 D]
+
diff --git a/gr-trellis/examples/python/fsm_files/awgn2o3_8ungerboecka.fsm b/gr-trellis/examples/python/fsm_files/awgn2o3_8ungerboecka.fsm
new file mode 100644
index 0000000000..2425e6a01a
--- /dev/null
+++ b/gr-trellis/examples/python/fsm_files/awgn2o3_8ungerboecka.fsm
@@ -0,0 +1,32 @@
+4 8 8
+
+0 4 1 5
+0 4 1 5
+0 4 1 5
+0 4 1 5
+2 6 3 7
+2 6 3 7
+2 6 3 7
+2 6 3 7
+
+0 4 2 6
+4 0 6 2
+2 6 0 4
+6 2 4 0
+1 5 3 7
+5 1 7 3
+3 7 1 5
+7 3 5 1
+
+This is the rate 2/3 Ungerboeck code with 8-states for 8-PSK (natural mapping).
+The states are defined in typical way.
+
+d_free^2 = 4.585 Es --> 6.6 dB (so gain of 3.6 dB over uncoded QPSK)
+
+Parity check matrix in octal: [04 02 11]
+
+Generator Matrix:
+
+[ 1 D 0
+ D^2 1 D]
+
diff --git a/gr-trellis/examples/python/fsm_files/uncoded4.fsm b/gr-trellis/examples/python/fsm_files/uncoded4.fsm
new file mode 100644
index 0000000000..67cb12ce8f
--- /dev/null
+++ b/gr-trellis/examples/python/fsm_files/uncoded4.fsm
@@ -0,0 +1,7 @@
+4 1 4
+
+0 0 0 0
+
+0 1 2 3
+
+uncoded 4-ary transmission
diff --git a/gr-trellis/examples/python/test_cpm.py b/gr-trellis/examples/python/test_cpm.py
index 3f5cfc4587..6fe25ec68c 100755
--- a/gr-trellis/examples/python/test_cpm.py
+++ b/gr-trellis/examples/python/test_cpm.py
@@ -12,8 +12,8 @@ from gnuradio import trellis, digital, filter, blocks
from grc_gnuradio import blks2 as grc_blks2
import math
import numpy
-import fsm_utils
from gnuradio import trellis
+from gnuradio.trellis import fsm_utils
try:
from gnuradio import analog
@@ -43,8 +43,9 @@ def run_test(seed,blocksize):
f = trellis.fsm(P,M,L)
# CPFSK signals
- #p = numpy.ones(Q)/(2.0)
- #q = numpy.cumsum(p)/(1.0*Q)
+ #p = numpy.ones(L*Q)
+ #q = numpy.cumsum(p)
+ #q = q/q[-1]/2.0;
# GMSK signals
BT=0.3;
diff --git a/gr-trellis/examples/python/test_pccc_turbo1.py b/gr-trellis/examples/python/test_pccc_turbo1.py
deleted file mode 100755
index 7104aa5039..0000000000
--- a/gr-trellis/examples/python/test_pccc_turbo1.py
+++ /dev/null
@@ -1,124 +0,0 @@
-#!/usr/bin/env python
-
-from gnuradio import gr
-from gnuradio import trellis, digital, blocks
-from gnuradio import eng_notation
-import math
-import sys
-import random
-import fsm_utils
-
-try:
- from gnuradio import analog
-except ImportError:
- sys.stderr.write("Error: Program requires gr-analog.\n")
- sys.exit(1)
-
-def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,Es,N0,IT,seed):
- tb = gr.top_block ()
-
-
- # TX
- src = blocks.lfsr_32k_source_s()
- src_head = blocks.head (gr.sizeof_short,Kb/16) # packet size in shorts
- s2fsmi = blocks.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the outer FSM input cardinality
- #src = blocks.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 = blocks.vector_sink_s()
- mod = digital.chunks_to_symbols_sf(constellation,dimensionality)
-
- # CHANNEL
- add = blocks.add_ff()
- noise = analog.noise_source_f(analog.GR_GAUSSIAN,math.sqrt(N0/2),seed)
-
- # RX
- metrics_in = trellis.metrics_f(fi.O()*fo.O(),dimensionality,constellation,digital.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for innner SISO
- scale = blocks.multiply_const_ff(1.0/N0)
- dec = trellis.pccc_decoder_s(fo,0,-1,fi,0,-1,interleaver,K,IT,trellis.TRELLIS_MIN_SUM)
-
- fsmi2s = blocks.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts
- dst = blocks.check_lfsr_32k_s()
-
- tb.connect (src,src_head,s2fsmi,enc,mod)
- #tb.connect (src,enc,mod)
- #tb.connect(enc,code)
- tb.connect (mod,(add,0))
- tb.connect (noise,(add,1))
- tb.connect (add,metrics_in,scale,dec,fsmi2s,dst)
-
- tb.run()
-
- #print code.data()
-
- ntotal = dst.ntotal ()
- nright = dst.nright ()
- runlength = dst.runlength ()
- return (ntotal,ntotal-nright)
-
-
-def main(args):
- nargs = len (args)
- if nargs == 5:
- fname_out=args[0]
- fname_in=args[1]
- esn0_db=float(args[2]) # Es/No in dB
- IT=int(args[3])
- rep=int(args[4]) # number of times the experiment is run to collect enough errors
- else:
- sys.stderr.write ('usage: test_pccc_turbo.py fsm_name_1 fsm_fname_2 Es/No_db iterations repetitions\n')
- sys.exit (1)
-
- # system parameters
- Kb=1024*16 # packet size in bits (make it multiple of 16 so it can be packed in a short)
- fo=trellis.fsm(fname_out) # get the outer FSM specification from a file
- fi=trellis.fsm(fname_in) # get the innner FSM specification from a file
- bitspersymbol = int(round(math.log(fo.I())/math.log(2))) # bits per FSM input symbol
- if fo.I() != fi.I():
- sys.stderr.write ('Incompatible input cardinality between two FSMs.\n')
- sys.exit (1)
- K=Kb/bitspersymbol # packet size in trellis steps
- interleaver=trellis.interleaver(K,666) # construct a random interleaver
- #modulation = fsm_utils.psk8 # see fsm_utlis.py for available predefined modulations
- dimensionality = 4
- constellation = [ 1, 0, 1, 0,\
- 1, 0,-1, 0,\
- 1, 0, 0, 1,\
- 1, 0, 0,-1,\
- -1, 0, 1, 0,\
- -1, 0,-1, 0,\
- -1, 0, 0, 1,\
- -1, 0, 0,-1,\
- 0, 1, 1, 0,\
- 0, 1,-1, 0,\
- 0, 1, 0, 1,\
- 0, 1, 0,-1,\
- 0,-1, 1, 0,\
- 0,-1,-1, 0,\
- 0,-1, 0, 1,\
- 0,-1, 0,-1,] # equivalent to 2 QPSK symbols
- if len(constellation)/dimensionality != fi.O()*fo.O():
- sys.stderr.write ('Incompatible FSM output cardinality and modulation size.\n')
- sys.exit (1)
- # calculate average symbol energy
- Es = 0
- for i in range(len(constellation)):
- Es = Es + constellation[i]**2
- Es = Es / (len(constellation)/dimensionality)
- N0=Es/pow(10.0,esn0_db/10.0); # calculate noise variance
-
- tot_s=0 # total number of transmitted shorts
- terr_s=0 # total number of shorts in error
- terr_p=0 # total number of packets in error
- for i in range(rep):
- (s,e)=run_test(fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,Es,N0,IT,-long(666+i)) # run experiment with different seed to get different noise realizations
- tot_s=tot_s+s
- terr_s=terr_s+e
- terr_p=terr_p+(terr_s!=0)
- if ((i+1)%10==0): # display progress
- print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
- # estimate of the (short or bit) error rate
- print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
-
-
-if __name__ == '__main__':
- main (sys.argv[1:])
diff --git a/gr-trellis/examples/python/test_sccc_hard.py b/gr-trellis/examples/python/test_sccc_hard.py
deleted file mode 100755
index 83393df4dc..0000000000
--- a/gr-trellis/examples/python/test_sccc_hard.py
+++ /dev/null
@@ -1,106 +0,0 @@
-#!/usr/bin/env python
-
-from gnuradio import gr
-from gnuradio import trellis, digital, blocks
-from gnuradio import eng_notation
-import math
-import sys
-import random
-import fsm_utils
-
-try:
- from gnuradio import analog
-except ImportError:
- sys.stderr.write("Error: Program requires gr-analog.\n")
- sys.exit(1)
-
-def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
- tb = gr.top_block ()
-
-
- # TX
- src = blocks.lfsr_32k_source_s()
- src_head = blocks.head(gr.sizeof_short,Kb/16) # packet size in shorts
- s2fsmi = blocks.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the outer FSM input cardinality
- 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 = digital.chunks_to_symbols_sf(constellation,dimensionality)
-
- # CHANNEL
- add = blocks.add_ff()
- noise = analog.noise_source_f(analog.GR_GAUSSIAN,math.sqrt(N0/2),seed)
-
- # RX
- metrics_in = trellis.metrics_f(fi.O(),dimensionality,constellation,digital.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for innner Viterbi
- va_in = trellis.viterbi_s(fi,K,0,-1) # Put -1 if the Initial/Final states are not set.
- deinter = trellis.permutation(interleaver.K(),interleaver.DEINTER(),1,gr.sizeof_short)
- metrics_out = trellis.metrics_s(fo.O(),1,[0,1,2,3],digital.TRELLIS_HARD_SYMBOL) # data preprocessing to generate metrics for outer Viterbi (hard decisions)
- va_out = trellis.viterbi_s(fo,K,0,-1) # Put -1 if the Initial/Final states are not set.
- fsmi2s = blocks.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts
- dst = blocks.check_lfsr_32k_s()
-
- tb.connect (src,src_head,s2fsmi,enc_out,inter,enc_in,mod)
- tb.connect (mod,(add,0))
- tb.connect (noise,(add,1))
- tb.connect (add,metrics_in)
- tb.connect (metrics_in,va_in,deinter,metrics_out,va_out,fsmi2s,dst)
-
- tb.run()
-
- ntotal = dst.ntotal ()
- nright = dst.nright ()
- runlength = dst.runlength ()
- return (ntotal,ntotal-nright)
-
-
-def main(args):
- nargs = len (args)
- if nargs == 4:
- fname_out=args[0]
- fname_in=args[1]
- esn0_db=float(args[2]) # Es/No in dB
- rep=int(args[3]) # number of times the experiment is run to collect enough errors
- else:
- sys.stderr.write ('usage: test_tcm.py fsm_name_out fsm_fname_in Es/No_db repetitions\n')
- sys.exit (1)
-
- # system parameters
- Kb=1024*16 # packet size in bits (make it multiple of 16 so it can be packed in a short)
- fo=trellis.fsm(fname_out) # get the outer FSM specification from a file
- fi=trellis.fsm(fname_in) # get the innner FSM specification from a file
- bitspersymbol = int(round(math.log(fo.I())/math.log(2))) # bits per FSM input symbol
- if fo.O() != fi.I():
- sys.stderr.write ('Incompatible cardinality between outer and inner FSM.\n')
- sys.exit (1)
- K=Kb/bitspersymbol # packet size in trellis steps
- interleaver=trellis.interleaver(K,666) # construct a random interleaver
- modulation = fsm_utils.psk8 # see fsm_utlis.py for available predefined modulations
- dimensionality = modulation[0]
- constellation = modulation[1]
- if len(constellation)/dimensionality != fi.O():
- sys.stderr.write ('Incompatible FSM output cardinality and modulation size.\n')
- sys.exit (1)
- # calculate average symbol energy
- Es = 0
- for i in range(len(constellation)):
- Es = Es + constellation[i]**2
- Es = Es / (len(constellation)/dimensionality)
- N0=Es/pow(10.0,esn0_db/10.0); # calculate noise variance
-
- tot_s=0 # total number of transmitted shorts
- terr_s=0 # total number of shorts in error
- terr_p=0 # total number of packets in error
- for i in range(rep):
- (s,e)=run_test(fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,N0,-long(666+i)) # run experiment with different seed to get different noise realizations
- tot_s=tot_s+s
- terr_s=terr_s+e
- terr_p=terr_p+(terr_s!=0)
- if ((i+1)%100==0) : # display progress
- print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
- # estimate of the (short or bit) error rate
- print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
-
-
-if __name__ == '__main__':
- main (sys.argv[1:])
diff --git a/gr-trellis/examples/python/test_sccc_soft.py b/gr-trellis/examples/python/test_sccc_soft.py
deleted file mode 100755
index 25d26e0025..0000000000
--- a/gr-trellis/examples/python/test_sccc_soft.py
+++ /dev/null
@@ -1,110 +0,0 @@
-#!/usr/bin/env python
-
-from gnuradio import gr
-from gnuradio import trellis, digital, blocks
-from gnuradio import eng_notation
-import math
-import sys
-import random
-import fsm_utils
-
-try:
- from gnuradio import analog
-except ImportError:
- sys.stderr.write("Error: Program requires gr-analog.\n")
- sys.exit(1)
-
-def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
- tb = gr.top_block ()
-
-
- # TX
- src = blocks.lfsr_32k_source_s()
- src_head = blocks.head (gr.sizeof_short,Kb/16) # packet size in shorts
- s2fsmi = blocks.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the outer FSM input cardinality
- 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 = digital.chunks_to_symbols_sf(constellation,dimensionality)
-
- # CHANNEL
- add = blocks.add_ff()
- noise = analog.noise_source_f(analog.GR_GAUSSIAN,math.sqrt(N0/2),seed)
-
- # RX
- metrics_in = trellis.metrics_f(fi.O(),dimensionality,constellation,digital.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for innner Viterbi
- gnd = blocks.vector_source_f([0],True);
- siso_in = trellis.siso_f(fi,K,0,-1,True,False,trellis.TRELLIS_MIN_SUM) # Put -1 if the Initial/Final states are not set.
- deinter = trellis.permutation(interleaver.K(),interleaver.DEINTER(),fi.I(),gr.sizeof_float)
- va_out = trellis.viterbi_s(fo,K,0,-1) # Put -1 if the Initial/Final states are not set.
- fsmi2s = blocks.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts
- dst = blocks.check_lfsr_32k_s()
-
- tb.connect (src,src_head,s2fsmi,enc_out,inter,enc_in,mod)
- tb.connect (mod,(add,0))
- tb.connect (noise,(add,1))
- tb.connect (add,metrics_in)
- tb.connect (gnd,(siso_in,0))
- tb.connect (metrics_in,(siso_in,1))
- tb.connect (siso_in,deinter,va_out,fsmi2s,dst)
-
- tb.run()
-
- ntotal = dst.ntotal ()
- nright = dst.nright ()
- runlength = dst.runlength ()
- return (ntotal,ntotal-nright)
-
-
-def main(args):
- nargs = len (args)
- if nargs == 4:
- fname_out=args[0]
- fname_in=args[1]
- esn0_db=float(args[2]) # Es/No in dB
- rep=int(args[3]) # number of times the experiment is run to collect enough errors
- else:
- sys.stderr.write ('usage: test_tcm.py fsm_name_out fsm_fname_in Es/No_db repetitions\n')
- sys.exit (1)
-
- # system parameters
- Kb=1024*16 # packet size in bits (make it multiple of 16 so it can be packed in a short)
- fo=trellis.fsm(fname_out) # get the outer FSM specification from a file
- fi=trellis.fsm(fname_in) # get the innner FSM specification from a file
- bitspersymbol = int(round(math.log(fo.I())/math.log(2))) # bits per FSM input symbol
- if fo.O() != fi.I():
- sys.stderr.write ('Incompatible cardinality between outer and inner FSM.\n')
- sys.exit (1)
- K=Kb/bitspersymbol # packet size in trellis steps
- interleaver=trellis.interleaver(K,666) # construct a random interleaver
- modulation = fsm_utils.psk8 # see fsm_utlis.py for available predefined modulations
- dimensionality = modulation[0]
- constellation = modulation[1]
- if len(constellation)/dimensionality != fi.O():
- sys.stderr.write ('Incompatible FSM output cardinality and modulation size.\n')
- sys.exit (1)
- # calculate average symbol energy
- Es = 0
- for i in range(len(constellation)):
- Es = Es + constellation[i]**2
- Es = Es / (len(constellation)/dimensionality)
- N0=Es/pow(10.0,esn0_db/10.0); # calculate noise variance
-
-
- tot_s=0 # total number of transmitted shorts
- terr_s=0 # total number of shorts in error
- terr_p=0 # total number of packets in error
- for i in range(rep):
- (s,e)=run_test(fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,N0,-long(666+i)) # run experiment with different seed to get different noise realizations
- tot_s=tot_s+s
- terr_s=terr_s+e
- terr_p=terr_p+(terr_s!=0)
- if ((i+1)%100==0) : # display progress
- print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
- # estimate of the (short or bit) error rate
- print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
-
-
-
-if __name__ == '__main__':
- main (sys.argv[1:])
diff --git a/gr-trellis/examples/python/test_sccc_turbo.py b/gr-trellis/examples/python/test_sccc_turbo.py
deleted file mode 100755
index 08004e8a0d..0000000000
--- a/gr-trellis/examples/python/test_sccc_turbo.py
+++ /dev/null
@@ -1,146 +0,0 @@
-#!/usr/bin/env python
-
-from gnuradio import gr
-from gnuradio import trellis, digital, blocks
-from gnuradio import eng_notation
-import math
-import sys
-import random
-import fsm_utils
-
-try:
- from gnuradio import analog
-except ImportError:
- sys.stderr.write("Error: Program requires gr-analog.\n")
- sys.exit(1)
-
-def make_rx(tb,fo,fi,dimensionality,constellation,K,interleaver,IT,Es,N0,type):
- metrics_in = trellis.metrics_f(fi.O(),dimensionality,constellation,digital.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for innner Viterbi
- scale = blocks.multiply_const_ff(1.0/N0)
- gnd = blocks.vector_source_f([0],True);
-
- inter=[]
- deinter=[]
- siso_in=[]
- siso_out=[]
-
- # generate all blocks
- for it in range(IT):
- inter.append( trellis.permutation(interleaver.K(),interleaver.INTER(),fi.I(),gr.sizeof_float) )
- siso_in.append( trellis.siso_f(fi,K,0,-1,True,False,type) )
- deinter.append( trellis.permutation(interleaver.K(),interleaver.DEINTER(),fi.I(),gr.sizeof_float) )
- if it < IT-1:
- siso_out.append( trellis.siso_f(fo,K,0,-1,False,True,type) )
- else:
- siso_out.append( trellis.viterbi_s(fo,K,0,-1) ) # no soft outputs needed
-
- # connect first stage
- tb.connect (gnd,inter[0])
- tb.connect (metrics_in,scale)
- tb.connect (scale,(siso_in[0],1))
-
- # connect the rest
- for it in range(IT):
- if it < IT-1:
- tb.connect (metrics_in,(siso_in[it+1],1))
- tb.connect (siso_in[it],deinter[it],(siso_out[it],1))
- tb.connect (gnd,(siso_out[it],0))
- tb.connect (siso_out[it],inter[it+1])
- tb.connect (inter[it],(siso_in[it],0))
- else:
- tb.connect (siso_in[it],deinter[it],siso_out[it])
- tb.connect (inter[it],(siso_in[it],0))
-
- return (metrics_in,siso_out[IT-1])
-
-
-def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,Es,N0,IT,seed):
- tb = gr.top_block ()
-
-
- # TX
- src = blocks.lfsr_32k_source_s()
- src_head = blocks.head(gr.sizeof_short,Kb/16) # packet size in shorts
- s2fsmi = blocks.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the outer FSM input cardinality
- 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 = digital.chunks_to_symbols_sf(constellation,dimensionality)
-
- # CHANNEL
- add = blocks.add_ff()
- noise = analog.noise_source_f(analog.GR_GAUSSIAN,math.sqrt(N0/2),seed)
-
- # RX
- (head,tail) = make_rx(tb,fo,fi,dimensionality,constellation,K,interleaver,IT,Es,N0,trellis.TRELLIS_MIN_SUM)
- #(head,tail) = make_rx(tb,fo,fi,dimensionality,constellation,K,interleaver,IT,Es,N0,trellis.TRELLIS_SUM_PRODUCT)
- fsmi2s = blocks.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts
- dst = blocks.check_lfsr_32k_s()
-
- tb.connect (src,src_head,s2fsmi,enc_out,inter,enc_in,mod)
- tb.connect (mod,(add,0))
- tb.connect (noise,(add,1))
- tb.connect (add,head)
- tb.connect (tail,fsmi2s,dst)
-
- tb.run()
-
- #print enc_out.ST(), enc_in.ST()
-
- ntotal = dst.ntotal ()
- nright = dst.nright ()
- runlength = dst.runlength ()
- return (ntotal,ntotal-nright)
-
-
-def main(args):
- nargs = len (args)
- if nargs == 5:
- fname_out=args[0]
- fname_in=args[1]
- esn0_db=float(args[2]) # Es/No in dB
- IT=int(args[3])
- rep=int(args[4]) # number of times the experiment is run to collect enough errors
- else:
- sys.stderr.write ('usage: test_sccc_turbo.py fsm_name_out fsm_fname_in Es/No_db iterations repetitions\n')
- sys.exit (1)
-
- # system parameters
- Kb=1024*16 # packet size in bits (make it multiple of 16 so it can be packed in a short)
- fo=trellis.fsm(fname_out) # get the outer FSM specification from a file
- fi=trellis.fsm(fname_in) # get the innner FSM specification from a file
- bitspersymbol = int(round(math.log(fo.I())/math.log(2))) # bits per FSM input symbol
- if fo.O() != fi.I():
- sys.stderr.write ('Incompatible cardinality between outer and inner FSM.\n')
- sys.exit (1)
- K=Kb/bitspersymbol # packet size in trellis steps
- interleaver=trellis.interleaver(K,666) # construct a random interleaver
- modulation = fsm_utils.psk8 # see fsm_utlis.py for available predefined modulations
- dimensionality = modulation[0]
- constellation = modulation[1]
- if len(constellation)/dimensionality != fi.O():
- sys.stderr.write ('Incompatible FSM output cardinality and modulation size.\n')
- sys.exit (1)
- # calculate average symbol energy
- Es = 0
- for i in range(len(constellation)):
- Es = Es + constellation[i]**2
- Es = Es / (len(constellation)/dimensionality)
- N0=Es/pow(10.0,esn0_db/10.0); # calculate noise variance
-
- tot_s=0 # total number of transmitted shorts
- terr_s=0 # total number of shorts in error
- terr_p=0 # total number of packets in error
- for i in range(rep):
- (s,e)=run_test(fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,Es,N0,IT,-long(666+i)) # run experiment with different seed to get different noise realizations
- tot_s=tot_s+s
- terr_s=terr_s+e
- terr_p=terr_p+(terr_s!=0)
- if ((i+1)%10==0): # display progress
- print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
- # estimate of the (short or bit) error rate
- print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
-
-
-if __name__ == '__main__':
- main (sys.argv[1:])
diff --git a/gr-trellis/examples/python/test_sccc_turbo1.py b/gr-trellis/examples/python/test_sccc_turbo1.py
deleted file mode 100755
index 528a79d011..0000000000
--- a/gr-trellis/examples/python/test_sccc_turbo1.py
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/usr/bin/env python
-
-from gnuradio import gr
-from gnuradio import trellis, digital, blocks
-from gnuradio import eng_notation
-import math
-import sys
-import random
-import fsm_utils
-
-try:
- from gnuradio import analog
-except ImportError:
- sys.stderr.write("Error: Program requires gr-analog.\n")
- sys.exit(1)
-
-def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,Es,N0,IT,seed):
- tb = gr.top_block ()
-
- # TX
- src = blocks.lfsr_32k_source_s()
- src_head = blocks.head(gr.sizeof_short,Kb/16) # packet size in shorts
- s2fsmi = blocks.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 = digital.chunks_to_symbols_sf(constellation,dimensionality)
-
- # CHANNEL
- add = blocks.add_ff()
- noise = analog.noise_source_f(analog.GR_GAUSSIAN,math.sqrt(N0/2),seed)
-
- # RX
- dec = trellis.sccc_decoder_combined_fs(fo,0,-1,fi,0,-1,interleaver,K,IT,trellis.TRELLIS_MIN_SUM,dimensionality,constellation,digital.TRELLIS_EUCLIDEAN,1.0)
- fsmi2s = blocks.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts
- dst = blocks.check_lfsr_32k_s()
-
- #tb.connect (src,src_head,s2fsmi,enc_out,inter,enc_in,mod)
- tb.connect (src,src_head,s2fsmi,enc,mod)
- tb.connect (mod,(add,0))
- tb.connect (noise,(add,1))
- #tb.connect (add,head)
- #tb.connect (tail,fsmi2s,dst)
- tb.connect (add,dec,fsmi2s,dst)
-
- tb.run()
-
- #print enc_out.ST(), enc_in.ST()
-
- ntotal = dst.ntotal ()
- nright = dst.nright ()
- runlength = dst.runlength ()
- return (ntotal,ntotal-nright)
-
-
-def main(args):
- nargs = len (args)
- if nargs == 5:
- fname_out=args[0]
- fname_in=args[1]
- esn0_db=float(args[2]) # Es/No in dB
- IT=int(args[3])
- rep=int(args[4]) # number of times the experiment is run to collect enough errors
- else:
- sys.stderr.write ('usage: test_tcm.py fsm_name_out fsm_fname_in Es/No_db iterations repetitions\n')
- sys.exit (1)
-
- # system parameters
- Kb=1024*16 # packet size in bits (make it multiple of 16 so it can be packed in a short)
- fo=trellis.fsm(fname_out) # get the outer FSM specification from a file
- fi=trellis.fsm(fname_in) # get the innner FSM specification from a file
- bitspersymbol = int(round(math.log(fo.I())/math.log(2))) # bits per FSM input symbol
- if fo.O() != fi.I():
- sys.stderr.write ('Incompatible cardinality between outer and inner FSM.\n')
- sys.exit (1)
- K=Kb/bitspersymbol # packet size in trellis steps
- interleaver=trellis.interleaver(K,666) # construct a random interleaver
- modulation = fsm_utils.psk8 # see fsm_utlis.py for available predefined modulations
- dimensionality = modulation[0]
- constellation = modulation[1]
- if len(constellation)/dimensionality != fi.O():
- sys.stderr.write ('Incompatible FSM output cardinality and modulation size.\n')
- sys.exit (1)
- # calculate average symbol energy
- Es = 0
- for i in range(len(constellation)):
- Es = Es + constellation[i]**2
- Es = Es / (len(constellation)/dimensionality)
- N0=Es/pow(10.0,esn0_db/10.0); # calculate noise variance
-
- tot_s=0 # total number of transmitted shorts
- terr_s=0 # total number of shorts in error
- terr_p=0 # total number of packets in error
- for i in range(rep):
- (s,e)=run_test(fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,Es,N0,IT,-long(666+i)) # run experiment with different seed to get different noise realizations
- tot_s=tot_s+s
- terr_s=terr_s+e
- terr_p=terr_p+(terr_s!=0)
- if ((i+1)%10==0): # display progress
- print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
- # estimate of the (short or bit) error rate
- print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
-
-
-if __name__ == '__main__':
- main (sys.argv[1:])
diff --git a/gr-trellis/examples/python/test_sccc_turbo2.py b/gr-trellis/examples/python/test_sccc_turbo2.py
deleted file mode 100755
index d7f26c4e13..0000000000
--- a/gr-trellis/examples/python/test_sccc_turbo2.py
+++ /dev/null
@@ -1,106 +0,0 @@
-#!/usr/bin/env python
-
-from gnuradio import gr
-from gnuradio import trellis, digital, blocks
-from gnuradio import eng_notation
-import math
-import sys
-import random
-import fsm_utils
-
-try:
- from gnuradio import analog
-except ImportError:
- sys.stderr.write("Error: Program requires gr-analog.\n")
- sys.exit(1)
-
-def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,Es,N0,IT,seed):
- tb = gr.top_block ()
-
- # TX
- src = blocks.lfsr_32k_source_s()
- src_head = blocks.head(gr.sizeof_short,Kb/16) # packet size in shorts
- s2fsmi = blocks.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 = digital.chunks_to_symbols_sf(constellation,dimensionality)
-
- # CHANNEL
- add = blocks.add_ff()
- noise = analog.noise_source_f(analog.GR_GAUSSIAN,math.sqrt(N0/2),seed)
-
- # RX
- metrics_in = trellis.metrics_f(fi.O(),dimensionality,constellation,digital.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for innner SISO
- scale = blocks.multiply_const_ff(1.0/N0)
- dec = trellis.sccc_decoder_s(fo,0,-1,fi,0,-1,interleaver,K,IT,trellis.TRELLIS_MIN_SUM)
- fsmi2s = blocks.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts
- dst = blocks.check_lfsr_32k_s()
-
- #tb.connect (src,src_head,s2fsmi,enc_out,inter,enc_in,mod)
- tb.connect (src,src_head,s2fsmi,enc,mod)
- tb.connect (mod,(add,0))
- tb.connect (noise,(add,1))
- #tb.connect (add,head)
- #tb.connect (tail,fsmi2s,dst)
- tb.connect (add,metrics_in,scale,dec,fsmi2s,dst)
-
- tb.run()
-
- #print enc_out.ST(), enc_in.ST()
-
- ntotal = dst.ntotal ()
- nright = dst.nright ()
- runlength = dst.runlength ()
- return (ntotal,ntotal-nright)
-
-
-def main(args):
- nargs = len (args)
- if nargs == 5:
- fname_out=args[0]
- fname_in=args[1]
- esn0_db=float(args[2]) # Es/No in dB
- IT=int(args[3])
- rep=int(args[4]) # number of times the experiment is run to collect enough errors
- else:
- sys.stderr.write ('usage: test_tcm.py fsm_name_out fsm_fname_in Es/No_db iterations repetitions\n')
- sys.exit (1)
-
- # system parameters
- Kb=1024*16 # packet size in bits (make it multiple of 16 so it can be packed in a short)
- fo=trellis.fsm(fname_out) # get the outer FSM specification from a file
- fi=trellis.fsm(fname_in) # get the innner FSM specification from a file
- bitspersymbol = int(round(math.log(fo.I())/math.log(2))) # bits per FSM input symbol
- if fo.O() != fi.I():
- sys.stderr.write ('Incompatible cardinality between outer and inner FSM.\n')
- sys.exit (1)
- K=Kb/bitspersymbol # packet size in trellis steps
- interleaver=trellis.interleaver(K,666) # construct a random interleaver
- modulation = fsm_utils.psk8 # see fsm_utlis.py for available predefined modulations
- dimensionality = modulation[0]
- constellation = modulation[1]
- if len(constellation)/dimensionality != fi.O():
- sys.stderr.write ('Incompatible FSM output cardinality and modulation size.\n')
- sys.exit (1)
- # calculate average symbol energy
- Es = 0
- for i in range(len(constellation)):
- Es = Es + constellation[i]**2
- Es = Es / (len(constellation)/dimensionality)
- N0=Es/pow(10.0,esn0_db/10.0); # calculate noise variance
-
- tot_s=0 # total number of transmitted shorts
- terr_s=0 # total number of shorts in error
- terr_p=0 # total number of packets in error
- for i in range(rep):
- (s,e)=run_test(fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,Es,N0,IT,-long(666+i)) # run experiment with different seed to get different noise realizations
- tot_s=tot_s+s
- terr_s=terr_s+e
- terr_p=terr_p+(terr_s!=0)
- if ((i+1)%10==0): # display progress
- print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
- # estimate of the (short or bit) error rate
- print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
-
-
-if __name__ == '__main__':
- main (sys.argv[1:])
diff --git a/gr-trellis/examples/python/test_tcm.py b/gr-trellis/examples/python/test_tcm.py
index bf9710aa1c..dfc565616e 100755
--- a/gr-trellis/examples/python/test_tcm.py
+++ b/gr-trellis/examples/python/test_tcm.py
@@ -6,9 +6,10 @@ from gnuradio import eng_notation
import math
import sys
import random
-import fsm_utils
+from gnuradio.trellis import fsm_utils
from gnuradio.eng_option import eng_option
from optparse import OptionParser
+import numpy
try:
from gnuradio import analog
@@ -19,39 +20,32 @@ except ImportError:
def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
tb = gr.top_block ()
-
# TX
- #packet = [0]*Kb
- #for i in range(Kb-1*16): # last 16 bits = 0 to drive the final state to 0
- #packet[i] = random.randint(0, 1) # random 0s and 1s
- #src = blocks.vector_source_s(packet,False)
- src = blocks.lfsr_32k_source_s()
- src_head = blocks.head(gr.sizeof_short,Kb/16) # packet size in shorts
- #b2s = blocks.unpacked_to_packed_ss(1,gr.GR_MSB_FIRST) # pack bits in shorts
+ numpy.random.seed(-seed)
+ packet = numpy.random.randint(0,2,Kb) # create Kb random bits
+ packet[Kb-10:Kb]=0
+ packet[0:Kb]=0
+ src = blocks.vector_source_s(packet.tolist(),False)
+ b2s = blocks.unpacked_to_packed_ss(1,gr.GR_MSB_FIRST) # pack bits in shorts
s2fsmi = blocks.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 = digital.chunks_to_symbols_sf(constellation,dimensionality)
# CHANNEL
add = blocks.add_ff()
- noise = analog.noise_source_f(analog.GR_GAUSSIAN,math.sqrt(N0/2),seed)
+ noise = analog.noise_source_f(analog.GR_GAUSSIAN,math.sqrt(N0/2),long(seed))
# RX
- metrics = trellis.metrics_f(f.O(),dimensionality,constellation,digital.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for Viterbi
- va = trellis.viterbi_s(f,K,0,-1) # Put -1 if the Initial/Final states are not set.
+ va = trellis.viterbi_combined_fs(f,K,0,0,dimensionality,constellation,digital.TRELLIS_EUCLIDEAN) # Put -1 if the Initial/Final states are not set.
fsmi2s = blocks.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts
- #s2b = blocks.packed_to_unpacked_ss(1,gr.GR_MSB_FIRST) # unpack shorts to bits
- #dst = blocks.vector_sink_s();
- dst = blocks.check_lfsr_32k_s()
+ s2b = blocks.packed_to_unpacked_ss(1,gr.GR_MSB_FIRST) # unpack shorts to bits
+ dst = blocks.vector_sink_s();
- tb.connect (src,src_head,s2fsmi,enc,mod)
- #tb.connect (src,b2s,s2fsmi,enc,mod)
+ tb.connect (src,b2s,s2fsmi,enc,mod)
tb.connect (mod,(add,0))
tb.connect (noise,(add,1))
- tb.connect (add,metrics)
- tb.connect (metrics,va,fsmi2s,dst)
- #tb.connect (metrics,va,fsmi2s,s2b,dst)
+ tb.connect (add,va,fsmi2s,s2b,dst)
tb.run()
@@ -61,19 +55,11 @@ def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
# Then put it as the last argument in the viterbi block
#print "final state = " , enc.ST()
- ntotal = dst.ntotal ()
- nright = dst.nright ()
- runlength = dst.runlength ()
- #ntotal = len(packet)
- #if len(dst.data()) != ntotal:
- #print "Error: not enough data\n"
- #nright = 0;
- #for i in range(ntotal):
- #if packet[i]==dst.data()[i]:
- #nright=nright+1
- #else:
- #print "Error in ", i
- return (ntotal,ntotal-nright)
+ if len(dst.data()) != len(packet):
+ print "Error: not enough data:", len(dst.data()), len(packet)
+ ntotal=len(packet)
+ nwrong = sum(abs(packet-numpy.array(dst.data())));
+ return (ntotal,nwrong,abs(packet-numpy.array(dst.data())))
@@ -113,20 +99,26 @@ def main():
Es = Es / (len(constellation)/dimensionality)
N0=Es/pow(10.0,esn0_db/10.0); # calculate noise variance
- tot_s=0 # total number of transmitted shorts
- terr_s=0 # total number of shorts in error
+ tot_b=0 # total number of transmitted bits
+ terr_b=0 # total number of bits in error
terr_p=0 # total number of packets in error
for i in range(rep):
- (s,e)=run_test(f,Kb,bitspersymbol,K,dimensionality,constellation,N0,-long(666+i)) # run experiment with different seed to get different noise realizations
- tot_s=tot_s+s
- terr_s=terr_s+e
- terr_p=terr_p+(terr_s!=0)
+ (b,e,pattern)=run_test(f,Kb,bitspersymbol,K,dimensionality,constellation,N0,-(666+i)) # run experiment with different seed to get different noise realizations
+ tot_b=tot_b+b
+ terr_b=terr_b+e
+ terr_p=terr_p+(e!=0)
if ((i+1)%100==0) : # display progress
- print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
- # estimate of the (short or bit) error rate
- print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
+ print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_b,terr_b, '%.2e' % ((1.0*terr_b)/tot_b)
+ if e!=0:
+ print "rep=",i, e
+ for k in range(Kb):
+ if pattern[k]!=0:
+ print k
+ # estimate of the bit error rate
+ print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_b,terr_b, '%.2e' % ((1.0*terr_b)/tot_b)
if __name__ == '__main__':
main()
+
diff --git a/gr-trellis/examples/python/test_tcm_bit.py b/gr-trellis/examples/python/test_tcm_bit.py
deleted file mode 100755
index 7880f0ea53..0000000000
--- a/gr-trellis/examples/python/test_tcm_bit.py
+++ /dev/null
@@ -1,134 +0,0 @@
-#!/usr/bin/env python
-
-from gnuradio import gr
-from gnuradio import trellis, digital, blocks
-from gnuradio import eng_notation
-import math
-import sys
-import random
-import fsm_utils
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-
-try:
- from gnuradio import analog
-except ImportError:
- sys.stderr.write("Error: Program requires gr-analog.\n")
- sys.exit(1)
-
-def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
- tb = gr.top_block ()
-
- # TX
- packet = [0]*Kb
- # this for loop is TOO slow!!!
- for i in range(Kb-1*16): # last 16 bits = 0 to drive the final state to 0
- packet[i] = random.randint(0, 1) # random 0s and 1s
- src = blocks.vector_source_s(packet,False)
- #src = blocks.lfsr_32k_source_s()
- #src_head = blocks.head (gr.sizeof_short,Kb/16) # packet size in shorts
- b2s = blocks.unpacked_to_packed_ss(1,gr.GR_MSB_FIRST) # pack bits in shorts
- s2fsmi = blocks.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 = digital.chunks_to_symbols_sf(constellation,dimensionality)
-
-
- # CHANNEL
- add = blocks.add_ff()
- noise = analog.noise_source_f(analog.GR_GAUSSIAN,math.sqrt(N0/2),seed)
-
-
- # RX
- metrics = trellis.metrics_f(f.O(),dimensionality,constellation,digital.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for Viterbi
- va = trellis.viterbi_s(f,K,0,-1) # Put -1 if the Initial/Final states are not set.
- fsmi2s = blocks.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts
- s2b = blocks.packed_to_unpacked_ss(1,gr.GR_MSB_FIRST) # unpack shorts to bits
- dst = blocks.vector_sink_s();
- #dst = blocks.check_lfsr_32k_s();
-
-
- #tb.connect (src,src_head,s2fsmi,enc,mod)
- tb.connect (src,b2s,s2fsmi,enc,mod)
- tb.connect (mod,(add,0))
- tb.connect (noise,(add,1))
- tb.connect (add,metrics)
- #tb.connect (metrics,va,fsmi2s,dst)
- tb.connect (metrics,va,fsmi2s,s2b,dst)
-
-
- tb.run()
-
- # A bit of cheating: run the program once and print the
- # final encoder state..
- # Then put it as the last argument in the viterbi block
- #print "final state = " , enc.ST()
-
- #ntotal = dst.ntotal ()
- #nright = dst.nright ()
- #runlength = dst.runlength ()
- ntotal = len(packet)
- if len(dst.data()) != ntotal:
- print "Error: not enough data\n"
- nright = 0;
- # this for loop is TOO slow!!!
- for i in range(ntotal):
- if packet[i]==dst.data()[i]:
- nright=nright+1
- #else:
- #print "Error in ", i
- return (ntotal,ntotal-nright)
-
-
-
-
-def main():
- parser = OptionParser(option_class=eng_option)
- parser.add_option("-f", "--fsm_file", type="string", default="fsm_files/awgn1o2_4.fsm", help="Filename containing the fsm specification, e.g. -f fsm_files/awgn1o2_4.fsm (default=fsm_files/awgn1o2_4.fsm)")
- parser.add_option("-e", "--esn0", type="eng_float", default=10.0, help="Symbol energy to noise PSD level ratio in dB, e.g., -e 10.0 (default=10.0)")
- parser.add_option("-r", "--repetitions", type="int", default=100, help="Number of packets to be generated for the simulation, e.g., -r 100 (default=100)")
-
- (options, args) = parser.parse_args ()
- if len(args) != 0:
- parser.print_help()
- raise SystemExit, 1
-
- fname=options.fsm_file
- esn0_db=float(options.esn0)
- rep=int(options.repetitions)
-
-
- # system parameters
- f=trellis.fsm(fname) # get the FSM specification from a file
- Kb=1024*16 # packet size in bits (make it multiple of 16 so it can be packed in a short)
- bitspersymbol = int(round(math.log(f.I())/math.log(2))) # bits per FSM input symbol
- K=Kb/bitspersymbol # packet size in trellis steps
- modulation = fsm_utils.psk4 # see fsm_utlis.py for available predefined modulations
- dimensionality = modulation[0]
- constellation = modulation[1]
- if len(constellation)/dimensionality != f.O():
- sys.stderr.write ('Incompatible FSM output cardinality and modulation size.\n')
- sys.exit (1)
- # calculate average symbol energy
- Es = 0
- for i in range(len(constellation)):
- Es = Es + constellation[i]**2
- Es = Es / (len(constellation)/dimensionality)
- N0=Es/pow(10.0,esn0_db/10.0); # calculate noise variance
-
- tot_s=0 # total number of transmitted shorts
- terr_s=0 # total number of shorts in error
- terr_p=0 # total number of packets in error
- for i in range(rep):
- (s,e)=run_test(f,Kb,bitspersymbol,K,dimensionality,constellation,N0,-long(666+i)) # run experiment with different seed to get different noise realizations
- tot_s=tot_s+s
- terr_s=terr_s+e
- terr_p=terr_p+(terr_s!=0)
- if ((i+1)%1==0) : # display progress
- print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
- # estimate of the (short or bit) error rate
- print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
-
-
-
-if __name__ == '__main__':
- main()
diff --git a/gr-trellis/examples/python/test_tcm_combined.py b/gr-trellis/examples/python/test_tcm_combined.py
deleted file mode 100755
index 697e3cc64a..0000000000
--- a/gr-trellis/examples/python/test_tcm_combined.py
+++ /dev/null
@@ -1,112 +0,0 @@
-#!/usr/bin/env python
-
-from gnuradio import gr
-from gnuradio import trellis, digital, blocks
-from gnuradio import eng_notation
-import math
-import sys
-import fsm_utils
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-
-try:
- from gnuradio import analog
-except ImportError:
- sys.stderr.write("Error: Program requires gr-analog.\n")
- sys.exit(1)
-
-def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
- tb = gr.top_block ()
-
- # TX
- src = blocks.lfsr_32k_source_s()
- src_head = blocks.head(gr.sizeof_short,Kb/16) # packet size in shorts
- s2fsmi = blocks.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 = digital.chunks_to_symbols_sf(constellation,dimensionality)
-
-
- # CHANNEL
- add = blocks.add_ff()
- noise = analog.noise_source_f(analog.GR_GAUSSIAN,math.sqrt(N0/2),seed)
-
-
- # RX
- va = trellis.viterbi_combined_fs(f,K,0,-1,dimensionality,constellation,digital.TRELLIS_EUCLIDEAN) # Put -1 if the Initial/Final states are not set.
- fsmi2s = blocks.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts
- dst = blocks.check_lfsr_32k_s();
-
-
- tb.connect (src,src_head,s2fsmi,enc,mod)
- tb.connect (mod,(add,0))
- tb.connect (noise,(add,1))
- tb.connect (add,va,fsmi2s,dst)
-
-
- tb.run()
-
- # A bit of cheating: run the program once and print the
- # final encoder state..
- # Then put it as the last argument in the viterbi block
- #print "final state = " , enc.ST()
-
- ntotal = dst.ntotal ()
- nright = dst.nright ()
- runlength = dst.runlength ()
-
- return (ntotal,ntotal-nright)
-
-
-
-
-def main():
- parser = OptionParser(option_class=eng_option)
- parser.add_option("-f", "--fsm_file", type="string", default="fsm_files/awgn1o2_4.fsm", help="Filename containing the fsm specification, e.g. -f fsm_files/awgn1o2_4.fsm (default=fsm_files/awgn1o2_4.fsm)")
- parser.add_option("-e", "--esn0", type="eng_float", default=10.0, help="Symbol energy to noise PSD level ratio in dB, e.g., -e 10.0 (default=10.0)")
- parser.add_option("-r", "--repetitions", type="int", default=100, help="Number of packets to be generated for the simulation, e.g., -r 100 (default=100)")
-
- (options, args) = parser.parse_args ()
- if len(args) != 0:
- parser.print_help()
- raise SystemExit, 1
-
- fname=options.fsm_file
- esn0_db=float(options.esn0)
- rep=int(options.repetitions)
-
- # system parameters
- f=trellis.fsm(fname) # get the FSM specification from a file (will hopefully be automated in the future...)
- Kb=1024*16 # packet size in bits (make it multiple of 16)
- bitspersymbol = int(round(math.log(f.I())/math.log(2))) # bits per FSM input symbol
- K=Kb/bitspersymbol # packet size in trellis steps
- modulation = fsm_utils.psk4 # see fsm_utils.py for available predefined modulations
- dimensionality = modulation[0]
- constellation = modulation[1]
- if len(constellation)/dimensionality != f.O():
- sys.stderr.write ('Incompatible FSM output cardinality and modulation size.\n')
- sys.exit (1)
- # calculate average symbol energy
- Es = 0
- for i in range(len(constellation)):
- Es = Es + constellation[i]**2
- Es = Es / (len(constellation)/dimensionality)
- N0=Es/pow(10.0,esn0_db/10.0); # noise variance
-
- tot_s=0 # total number of transmitted shorts
- terr_s=0 # total number of shorts in error
- terr_p=0 # total number of packets in error
- for i in range(rep):
- (s,e)=run_test(f,Kb,bitspersymbol,K,dimensionality,constellation,N0,-long(666+i)) # run experiment with different seed to get different noise realizations
- tot_s=tot_s+s
- terr_s=terr_s+e
- terr_p=terr_p+(terr_s!=0)
- if ((i+1)%100==0) : # display progress
- print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
- # estimate of the (short or bit) error rate
- print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
-
-
-
-if __name__ == '__main__':
- main()
-
diff --git a/gr-trellis/examples/python/test_tcm_parallel.py b/gr-trellis/examples/python/test_tcm_parallel.py
deleted file mode 100755
index b30c80811f..0000000000
--- a/gr-trellis/examples/python/test_tcm_parallel.py
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/usr/bin/env python
-
-from gnuradio import gr
-from gnuradio import trellis, digital, blocks
-from gnuradio import eng_notation
-import math
-import sys
-import fsm_utils
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-
-try:
- from gnuradio import analog
-except ImportError:
- sys.stderr.write("Error: Program requires gr-analog.\n")
- sys.exit(1)
-
-def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed,P):
- tb = gr.top_block ()
-
- # TX
- src = blocks.lfsr_32k_source_s()
- src_head = blocks.head(gr.sizeof_short,Kb/16*P) # packet size in shorts
- s2fsmi=blocks.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the FSM input cardinality
- s2p = blocks.stream_to_streams(gr.sizeof_short,P) # serial to parallel
- enc = trellis.encoder_ss(f,0) # initiali state = 0
- mod = digital.chunks_to_symbols_sf(constellation,dimensionality)
-
- # CHANNEL
- add=[]
- noise=[]
- for i in range(P):
- add.append(blocks.add_ff())
- noise.append(analog.noise_source_f(analog.GR_GAUSSIAN,math.sqrt(N0/2),seed))
-
- # RX
- metrics = trellis.metrics_f(f.O(),dimensionality,constellation,digital.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for Viterbi
- va = trellis.viterbi_s(f,K,0,-1) # Put -1 if the Initial/Final states are not set.
- p2s = blocks.streams_to_stream(gr.sizeof_short,P) # parallel to serial
- fsmi2s=blocks.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts
- dst = blocks.check_lfsr_32k_s()
-
- tb.connect (src,src_head,s2fsmi,s2p)
- for i in range(P):
- tb.connect ((s2p,i),(enc,i),(mod,i))
- tb.connect ((mod,i),(add[i],0))
- tb.connect (noise[i],(add[i],1))
- tb.connect (add[i],(metrics,i))
- tb.connect ((metrics,i),(va,i),(p2s,i))
- tb.connect (p2s,fsmi2s,dst)
-
-
- tb.run()
-
- # A bit of cheating: run the program once and print the
- # final encoder state.
- # Then put it as the last argument in the viterbi block
- #print "final state = " , enc.ST()
-
- ntotal = dst.ntotal ()
- nright = dst.nright ()
- runlength = dst.runlength ()
-
- return (ntotal,ntotal-nright)
-
-
-
-def main():
- parser = OptionParser(option_class=eng_option)
- parser.add_option("-f", "--fsm_file", type="string", default="fsm_files/awgn1o2_4.fsm", help="Filename containing the fsm specification, e.g. -f fsm_files/awgn1o2_4.fsm (default=fsm_files/awgn1o2_4.fsm)")
- parser.add_option("-e", "--esn0", type="eng_float", default=10.0, help="Symbol energy to noise PSD level ratio in dB, e.g., -e 10.0 (default=10.0)")
- parser.add_option("-r", "--repetitions", type="int", default=100, help="Number of packets to be generated for the simulation, e.g., -r 100 (default=100)")
-
- (options, args) = parser.parse_args ()
- if len(args) != 0:
- parser.print_help()
- raise SystemExit, 1
-
- fname=options.fsm_file
- esn0_db=float(options.esn0)
- rep=int(options.repetitions)
-
- # system parameters
- f=trellis.fsm(fname) # get the FSM specification from a file
- P=4 # how many parallel streams?
- Kb=1024*16 # packet size in bits (make it multiple of 16 so it can be packed in a short)
- bitspersymbol = int(round(math.log(f.I())/math.log(2))) # bits per FSM input symbol
- K=Kb/bitspersymbol # packet size in trellis steps
- modulation = fsm_utils.psk4 # see fsm_utlis.py for available predefined modulations
- dimensionality = modulation[0]
- constellation = modulation[1]
- if len(constellation)/dimensionality != f.O():
- sys.stderr.write ('Incompatible FSM output cardinality and modulation size.\n')
- sys.exit (1)
- # calculate average symbol energy
- Es = 0
- for i in range(len(constellation)):
- Es = Es + constellation[i]**2
- Es = Es / (len(constellation)/dimensionality)
- N0=Es/pow(10.0,esn0_db/10.0); # calculate noise variance
-
- tot_s=0 # total number of transmitted shorts
- terr_s=0 # total number of shorts in error
- terr_p=0 # total number of packets in error
- for i in range(rep):
- (s,e)=run_test(f,Kb,bitspersymbol,K,dimensionality,constellation,N0,-long(666+i),P) # run experiment with different seed to get different noise realizations
- tot_s=tot_s+s
- terr_s=terr_s+e
- terr_p=terr_p+(terr_s!=0)
- if ((i+1)%100==0) : # display progress
- print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
- # estimate of the (short or bit) error rate
- print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
-
-
-if __name__ == '__main__':
- main()
-
diff --git a/gr-trellis/examples/python/test_turbo_equalization.py b/gr-trellis/examples/python/test_turbo_equalization.py
deleted file mode 100755
index b2d58a6014..0000000000
--- a/gr-trellis/examples/python/test_turbo_equalization.py
+++ /dev/null
@@ -1,147 +0,0 @@
-#!/usr/bin/env python
-
-from gnuradio import gr
-from gnuradio import trellis, digital, blocks
-from gnuradio import eng_notation
-import math
-import sys
-import fsm_utils
-
-try:
- from gnuradio import analog
-except ImportError:
- sys.stderr.write("Error: Program requires gr-analog.\n")
- sys.exit(1)
-
-def make_rx(tb,fo,fi,dimensionality,tot_constellation,K,interleaver,IT,Es,N0,type):
- metrics_in = trellis.metrics_f(fi.O(),dimensionality,tot_constellation,digital.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for innner SISO
- scale = blocks.multiply_const_ff(1.0/N0)
- gnd = blocks.vector_source_f([0],True);
-
- inter=[]
- deinter=[]
- siso_in=[]
- siso_out=[]
-
- # generate all blocks
- for it in range(IT):
- inter.append( trellis.permutation(interleaver.K(),interleaver.INTER(),fi.I(),gr.sizeof_float) )
- siso_in.append( trellis.siso_f(fi,K,0,-1,True,False,type) )
- deinter.append( trellis.permutation(interleaver.K(),interleaver.DEINTER(),fi.I(),gr.sizeof_float) )
- if it < IT-1:
- siso_out.append( trellis.siso_f(fo,K,0,-1,False,True,type) )
- else:
- siso_out.append( trellis.viterbi_s(fo,K,0,-1) ) # no soft outputs needed
-
- # connect first stage
- tb.connect (gnd,inter[0])
- tb.connect (metrics_in,scale)
- tb.connect (scale,(siso_in[0],1))
-
- # connect the rest
- for it in range(IT):
- if it < IT-1:
- tb.connect (metrics_in,(siso_in[it+1],1))
- tb.connect (siso_in[it],deinter[it],(siso_out[it],1))
- tb.connect (gnd,(siso_out[it],0))
- tb.connect (siso_out[it],inter[it+1])
- tb.connect (inter[it],(siso_in[it],0))
- else:
- tb.connect (siso_in[it],deinter[it],siso_out[it])
- tb.connect (inter[it],(siso_in[it],0))
-
- return (metrics_in,siso_out[IT-1])
-
-
-def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,tot_constellation,Es,N0,IT,seed):
- tb = gr.top_block ()
-
- # TX
- src = blocks.lfsr_32k_source_s()
- src_head = blocks.head(gr.sizeof_short,Kb/16) # packet size in shorts
- s2fsmi = blocks.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the iouter FSM input cardinality
- 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
- # 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 = digital.chunks_to_symbols_sf(tot_constellation,dimensionality)
-
- # CHANNEL
- add = blocks.add_ff()
- noise = analog.noise_source_f(analog.GR_GAUSSIAN,math.sqrt(N0/2),seed)
-
- # RX
- (head,tail) = make_rx(tb,fo,fi,dimensionality,tot_constellation,K,interleaver,IT,Es,N0,trellis.TRELLIS_MIN_SUM)
- fsmi2s = blocks.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts
- dst = blocks.check_lfsr_32k_s();
-
- tb.connect (src,src_head,s2fsmi,enc_out,inter,enc_in,mod)
- tb.connect (mod,(add,0))
- tb.connect (noise,(add,1))
- tb.connect (add,head)
- tb.connect (tail,fsmi2s,dst)
-
- tb.run()
-
- ntotal = dst.ntotal ()
- nright = dst.nright ()
- runlength = dst.runlength ()
- #print ntotal,nright,runlength
-
- return (ntotal,ntotal-nright)
-
-
-
-
-def main(args):
- nargs = len (args)
- if nargs == 3:
- fname_out=args[0]
- esn0_db=float(args[1])
- rep=int(args[2])
- else:
- sys.stderr.write ('usage: test_turbo_equalization.py fsm_name_out Es/No_db repetitions\n')
- sys.exit (1)
-
- # system parameters
- Kb=64*16 # packet size in bits (multiple of 16)
- modulation = fsm_utils.pam4 # see fsm_utlis.py for available predefined modulations
- channel = fsm_utils.c_channel # see fsm_utlis.py for available predefined test channels
- fo=trellis.fsm(fname_out) # get the outer FSM specification from a file
- fi=trellis.fsm(len(modulation[1]),len(channel)) # generate the FSM automatically
- if fo.O() != fi.I():
- sys.stderr.write ('Incompatible cardinality between outer and inner FSM.\n')
- sys.exit (1)
- bitspersymbol = int(round(math.log(fo.I())/math.log(2))) # bits per FSM input symbol
- K=Kb/bitspersymbol # packet size in trellis steps
- print 'size = ',K
- interleaver=trellis.interleaver(K,666) # construct a random interleaver
- tot_channel = fsm_utils.make_isi_lookup(modulation,channel,True) # generate the lookup table (normalize energy to 1)
- dimensionality = tot_channel[0]
- tot_constellation = tot_channel[1]
- if len(tot_constellation)/dimensionality != fi.O():
- sys.stderr.write ('Incompatible FSM output cardinality and lookup table size.\n')
- sys.exit (1)
- N0=pow(10.0,-esn0_db/10.0); # noise variance
- IT = 3 # number of turbo iterations
-
- tot_s=0 # total number of transmitted shorts
- terr_s=0 # total number of shorts in error
- terr_p=0 # total number of packets in error
-
- for i in range(rep):
- (s,e)=run_test(fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,tot_constellation,1,N0,IT,-long(666+i)) # run experiment with different seed to get different noise realizations
- print s
- tot_s=tot_s+s
- terr_s=terr_s+e
- terr_p=terr_p+(terr_s!=0)
- if ((i+1)%10==0) : # display progress
- print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
- # estimate of the (short or bit) error rate
- print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
-
-
-
-if __name__ == '__main__':
- main (sys.argv[1:])
-
diff --git a/gr-trellis/examples/python/test_turbo_equalization1.py b/gr-trellis/examples/python/test_turbo_equalization1.py
deleted file mode 100755
index 5ff21ec757..0000000000
--- a/gr-trellis/examples/python/test_turbo_equalization1.py
+++ /dev/null
@@ -1,152 +0,0 @@
-#!/usr/bin/env python
-
-from gnuradio import gr
-from gnuradio import trellis, digital, filter, blocks
-from gnuradio import eng_notation
-import math
-import sys
-import random
-import fsm_utils
-
-try:
- from gnuradio import analog
-except ImportError:
- sys.stderr.write("Error: Program requires gr-analog.\n")
- sys.exit(1)
-
-def make_rx(tb,fo,fi,dimensionality,tot_constellation,K,interleaver,IT,Es,N0,type):
- metrics_in = trellis.metrics_f(fi.O(),dimensionality,tot_constellation,digital.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for innner SISO
- scale = blocks.multiply_const_ff(1.0/N0)
- gnd = blocks.vector_source_f([0],True);
-
- inter=[]
- deinter=[]
- siso_in=[]
- siso_out=[]
-
- # generate all blocks
- for it in range(IT):
- inter.append( trellis.permutation(interleaver.K(),interleaver.INTER(),fi.I(),gr.sizeof_float) )
- siso_in.append( trellis.siso_f(fi,K,0,-1,True,False,type) )
- deinter.append( trellis.permutation(interleaver.K(),interleaver.DEINTER(),fi.I(),gr.sizeof_float) )
- if it < IT-1:
- siso_out.append( trellis.siso_f(fo,K,0,-1,False,True,type) )
- else:
- siso_out.append( trellis.viterbi_s(fo,K,0,-1) ) # no soft outputs needed
-
- # connect first stage
- tb.connect (gnd,inter[0])
- tb.connect (metrics_in,scale)
- tb.connect (scale,(siso_in[0],1))
-
- # connect the rest
- for it in range(IT):
- if it < IT-1:
- tb.connect (scale,(siso_in[it+1],1))
- tb.connect (siso_in[it],deinter[it],(siso_out[it],1))
- tb.connect (gnd,(siso_out[it],0))
- tb.connect (siso_out[it],inter[it+1])
- tb.connect (inter[it],(siso_in[it],0))
- else:
- tb.connect (siso_in[it],deinter[it],siso_out[it])
- tb.connect (inter[it],(siso_in[it],0))
-
- return (metrics_in,siso_out[IT-1])
-
-
-def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,channel,modulation,dimensionality,tot_constellation,Es,N0,IT,seed):
- tb = gr.top_block ()
- L = len(channel)
-
- # TX
- # this for loop is TOO slow in python!!!
- packet = [0]*(K)
- random.seed(seed)
- for i in range(len(packet)):
- packet[i] = random.randint(0, 2**bitspersymbol - 1) # random symbols
- src = blocks.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 = digital.chunks_to_symbols_sf(modulation[1],modulation[0])
-
- # CHANNEL
- isi = filter.fir_filter_fff(1,channel)
- add = blocks.add_ff()
- noise = analog.noise_source_f(analog.GR_GAUSSIAN,math.sqrt(N0/2),seed)
-
- # RX
- (head,tail) = make_rx(tb,fo,fi,dimensionality,tot_constellation,K,interleaver,IT,Es,N0,trellis.TRELLIS_MIN_SUM)
- dst = blocks.vector_sink_s();
-
- tb.connect (src,enc_out,inter,mod)
- tb.connect (mod,isi,(add,0))
- tb.connect (noise,(add,1))
- tb.connect (add,head)
- tb.connect (tail,dst)
-
- tb.run()
-
- data = dst.data()
- ntotal = len(data)
- nright=0
- for i in range(ntotal):
- if packet[i]==data[i]:
- nright=nright+1
- #else:
- #print "Error in ", i
-
- return (ntotal,ntotal-nright)
-
-
-
-
-def main(args):
- nargs = len (args)
- if nargs == 3:
- fname_out=args[0]
- esn0_db=float(args[1])
- rep=int(args[2])
- else:
- sys.stderr.write ('usage: test_turbo_equalization.py fsm_name_out Es/No_db repetitions\n')
- sys.exit (1)
-
- # system parameters
- Kb=64*16 # packet size in bits (multiple of 16)
- modulation = fsm_utils.pam4 # see fsm_utlis.py for available predefined modulations
- channel = fsm_utils.c_channel # see fsm_utlis.py for available predefined test channels
- fo=trellis.fsm(fname_out) # get the outer FSM specification from a file
- fi=trellis.fsm(len(modulation[1]),len(channel)) # generate the FSM automatically
- if fo.O() != fi.I():
- sys.stderr.write ('Incompatible cardinality between outer and inner FSM.\n')
- sys.exit (1)
- bitspersymbol = int(round(math.log(fo.I())/math.log(2))) # bits per FSM input symbol
- K=Kb/bitspersymbol # packet size in trellis steps
- interleaver=trellis.interleaver(K,666) # construct a random interleaver
- tot_channel = fsm_utils.make_isi_lookup(modulation,channel,True) # generate the lookup table (normalize energy to 1)
- dimensionality = tot_channel[0]
- tot_constellation = tot_channel[1]
- if len(tot_constellation)/dimensionality != fi.O():
- sys.stderr.write ('Incompatible FSM output cardinality and lookup table size.\n')
- sys.exit (1)
- N0=pow(10.0,-esn0_db/10.0); # noise variance
- IT = 3 # number of turbo iterations
-
- tot_s=0 # total number of transmitted shorts
- terr_s=0 # total number of shorts in error
- terr_p=0 # total number of packets in error
-
- for i in range(rep):
- (s,e)=run_test(fo,fi,interleaver,Kb,bitspersymbol,K,channel,modulation,dimensionality,tot_constellation,1,N0,IT,-long(666+i)) # run experiment with different seed to get different noise realizations
- tot_s=tot_s+s
- terr_s=terr_s+e
- terr_p=terr_p+(terr_s!=0)
- if ((i+1)%10==0) : # display progress
- print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
- # estimate of the (short or bit) error rate
- print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
-
-
-
-if __name__ == '__main__':
- main (sys.argv[1:])
-
diff --git a/gr-trellis/examples/python/test_turbo_equalization2.py b/gr-trellis/examples/python/test_turbo_equalization2.py
deleted file mode 100755
index c2af9fbfca..0000000000
--- a/gr-trellis/examples/python/test_turbo_equalization2.py
+++ /dev/null
@@ -1,152 +0,0 @@
-#!/usr/bin/env python
-
-from gnuradio import gr
-from gnuradio import trellis, digital, filter, blocks
-from gnuradio import eng_notation
-import math
-import sys
-import random
-import fsm_utils
-
-try:
- from gnuradio import analog
-except ImportError:
- sys.stderr.write("Error: Program requires gr-analog.\n")
- sys.exit(1)
-
-def make_rx(tb,fo,fi,dimensionality,tot_constellation,K,interleaver,IT,Es,N0,type):
- scale = blocks.multiply_const_ff(math.sqrt(1.0/N0))
- gnd = blocks.vector_source_f([0],True);
-
- inter=[]
- deinter=[]
- siso_in=[]
- siso_out=[]
-
- # generate all blocks
- for it in range(IT):
- inter.append( trellis.permutation(interleaver.K(),interleaver.INTER(),fi.I(),gr.sizeof_float) )
- siso_in.append( trellis.siso_combined_f(fi,K,0,-1,True,False,type,dimensionality,tot_constellation,digital.TRELLIS_EUCLIDEAN) )
- deinter.append( trellis.permutation(interleaver.K(),interleaver.DEINTER(),fi.I(),gr.sizeof_float) )
- if it < IT-1:
- siso_out.append( trellis.siso_f(fo,K,0,-1,False,True,type) )
- else:
- siso_out.append( trellis.viterbi_s(fo,K,0,-1) ) # no soft outputs needed
-
- # connect first stage
- tb.connect (gnd,inter[0])
- tb.connect (scale,(siso_in[0],1))
-
- # connect the rest
- for it in range(IT):
- if it < IT-1:
- tb.connect (scale,(siso_in[it+1],1))
- tb.connect (siso_in[it],deinter[it],(siso_out[it],1))
- tb.connect (gnd,(siso_out[it],0))
- tb.connect (siso_out[it],inter[it+1])
- tb.connect (inter[it],(siso_in[it],0))
- else:
- tb.connect (siso_in[it],deinter[it],siso_out[it])
- tb.connect (inter[it],(siso_in[it],0))
-
- return (scale,siso_out[IT-1])
-
-
-def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,channel,modulation,dimensionality,tot_constellation,Es,N0,IT,seed):
- tb = gr.top_block ()
- L = len(channel)
-
- # TX
- # this for loop is TOO slow in python!!!
- packet = [0]*(K)
- random.seed(seed)
- for i in range(len(packet)):
- packet[i] = random.randint(0, 2**bitspersymbol - 1) # random symbols
- src = blocks.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 = digital.chunks_to_symbols_sf(modulation[1],modulation[0])
-
- # CHANNEL
- isi = filter.fir_filter_fff(1,channel)
- add = blocks.add_ff()
- noise = analog.noise_source_f(analog.GR_GAUSSIAN,math.sqrt(N0/2),seed)
-
- # RX
- (head,tail) = make_rx(tb,fo,fi,dimensionality,tot_constellation,K,interleaver,IT,Es,N0,trellis.TRELLIS_MIN_SUM)
- dst = blocks.vector_sink_s();
-
- tb.connect (src,enc_out,inter,mod)
- tb.connect (mod,isi,(add,0))
- tb.connect (noise,(add,1))
- tb.connect (add,head)
- tb.connect (tail,dst)
-
- tb.run()
-
- data = dst.data()
- ntotal = len(data)
- nright=0
- for i in range(ntotal):
- if packet[i]==data[i]:
- nright=nright+1
- #else:
- #print "Error in ", i
-
- return (ntotal,ntotal-nright)
-
-
-
-
-def main(args):
- nargs = len (args)
- if nargs == 3:
- fname_out=args[0]
- esn0_db=float(args[1])
- rep=int(args[2])
- else:
- sys.stderr.write ('usage: test_turbo_equalization.py fsm_name_out Es/No_db repetitions\n')
- sys.exit (1)
-
- # system parameters
- Kb=64*16 # packet size in bits (multiple of 16)
- modulation = fsm_utils.pam4 # see fsm_utlis.py for available predefined modulations
- channel = fsm_utils.c_channel # see fsm_utlis.py for available predefined test channels
- fo=trellis.fsm(fname_out) # get the outer FSM specification from a file
- fi=trellis.fsm(len(modulation[1]),len(channel)) # generate the FSM automatically
- if fo.O() != fi.I():
- sys.stderr.write ('Incompatible cardinality between outer and inner FSM.\n')
- sys.exit (1)
- bitspersymbol = int(round(math.log(fo.I())/math.log(2))) # bits per FSM input symbol
- K=Kb/bitspersymbol # packet size in trellis steps
- interleaver=trellis.interleaver(K,666) # construct a random interleaver
- tot_channel = fsm_utils.make_isi_lookup(modulation,channel,True) # generate the lookup table (normalize energy to 1)
- dimensionality = tot_channel[0]
- N0=pow(10.0,-esn0_db/10.0); # noise variance
- tot_constellation =[0]*len(tot_channel[1])
- for i in range(len(tot_channel[1])):
- tot_constellation[i] = tot_channel[1][i] * math.sqrt(1.0/N0)
- if len(tot_constellation)/dimensionality != fi.O():
- sys.stderr.write ('Incompatible FSM output cardinality and lookup table size.\n')
- sys.exit (1)
- IT = 3 # number of turbo iterations
-
- tot_s=0 # total number of transmitted shorts
- terr_s=0 # total number of shorts in error
- terr_p=0 # total number of packets in error
-
- for i in range(rep):
- (s,e)=run_test(fo,fi,interleaver,Kb,bitspersymbol,K,channel,modulation,dimensionality,tot_constellation,1,N0,IT,-long(666+i)) # run experiment with different seed to get different noise realizations
- tot_s=tot_s+s
- terr_s=terr_s+e
- terr_p=terr_p+(terr_s!=0)
- if ((i+1)%10==0) : # display progress
- print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
- # estimate of the (short or bit) error rate
- print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
-
-
-
-if __name__ == '__main__':
- main (sys.argv[1:])
-
diff --git a/gr-trellis/examples/python/test_viterbi_equalization.py b/gr-trellis/examples/python/test_viterbi_equalization.py
deleted file mode 100755
index 987f171b2a..0000000000
--- a/gr-trellis/examples/python/test_viterbi_equalization.py
+++ /dev/null
@@ -1,99 +0,0 @@
-#!/usr/bin/env python
-
-from gnuradio import gr
-from gnuradio import trellis, digital, blocks
-from gnuradio import eng_notation
-import math
-import sys
-import fsm_utils
-
-try:
- from gnuradio import analog
-except ImportError:
- sys.stderr.write("Error: Program requires gr-analog.\n")
- sys.exit(1)
-
-def run_test (f,Kb,bitspersymbol,K,dimensionality,tot_constellation,N0,seed):
- tb = gr.top_block ()
-
- # TX
- src = blocks.lfsr_32k_source_s()
- src_head = blocks.head (gr.sizeof_short,Kb/16) # packet size in shorts
- s2fsmi = blocks.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 = digital.chunks_to_symbols_sf(tot_constellation,dimensionality)
-
- # CHANNEL
- add = blocks.add_ff()
- noise = analog.noise_source_f(analog.GR_GAUSSIAN,math.sqrt(N0/2),seed)
-
- # RX
- metrics = trellis.metrics_f(f.O(),dimensionality,tot_constellation,digital.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for Viterbi
- va = trellis.viterbi_s(f,K,0,-1) # Put -1 if the Initial/Final states are not set.
- fsmi2s = blocks.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts
- dst = blocks.check_lfsr_32k_s();
-
- tb.connect (src,src_head,s2fsmi,enc,mod)
- tb.connect (mod,(add,0))
- tb.connect (noise,(add,1))
- tb.connect (add,metrics)
- tb.connect (metrics,va,fsmi2s,dst)
-
- tb.run()
-
- ntotal = dst.ntotal ()
- nright = dst.nright ()
- runlength = dst.runlength ()
- #print ntotal,nright,runlength
-
- return (ntotal,ntotal-nright)
-
-
-
-
-def main(args):
- nargs = len (args)
- if nargs == 2:
- esn0_db=float(args[0])
- rep=int(args[1])
- else:
- sys.stderr.write ('usage: test_viterbi_equalization.py Es/No_db repetitions\n')
- sys.exit (1)
-
- # system parameters
- Kb=128*16 # packet size in bits (multiple of 16)
- modulation = fsm_utils.pam4 # see fsm_utlis.py for available predefined modulations
- channel = fsm_utils.c_channel # see fsm_utlis.py for available predefined test channels
- f=trellis.fsm(len(modulation[1]),len(channel)) # generate the FSM automatically
- bitspersymbol = int(round(math.log(f.I())/math.log(2))) # bits per FSM input symbol
- K=Kb/bitspersymbol # packet size in trellis steps
-
- tot_channel = fsm_utils.make_isi_lookup(modulation,channel,True) # generate the lookup table (normalize energy to 1)
- dimensionality = tot_channel[0]
- tot_constellation = tot_channel[1]
- N0=pow(10.0,-esn0_db/10.0); # noise variance
- if len(tot_constellation)/dimensionality != f.O():
- sys.stderr.write ('Incompatible FSM output cardinality and lookup table size.\n')
- sys.exit (1)
-
-
- tot_s=0 # total number of transmitted shorts
- terr_s=0 # total number of shorts in error
- terr_p=0 # total number of packets in error
-
- for i in range(rep):
- (s,e)=run_test(f,Kb,bitspersymbol,K,dimensionality,tot_constellation,N0,-long(666+i)) # run experiment with different seed to get different noise realizations
- tot_s=tot_s+s
- terr_s=terr_s+e
- terr_p=terr_p+(terr_s!=0)
- if ((i+1)%100==0) : # display progress
- print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
- # estimate of the (short or bit) error rate
- print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
-
-
-
-if __name__ == '__main__':
- main (sys.argv[1:])
-
diff --git a/gr-trellis/examples/python/test_viterbi_equalization1.py b/gr-trellis/examples/python/test_viterbi_equalization1.py
deleted file mode 100755
index baa6a27f1b..0000000000
--- a/gr-trellis/examples/python/test_viterbi_equalization1.py
+++ /dev/null
@@ -1,108 +0,0 @@
-#!/usr/bin/env python
-
-from gnuradio import gr
-from gnuradio import trellis, digital, filter, blocks
-from gnuradio import eng_notation
-import math
-import sys
-import random
-import fsm_utils
-
-try:
- from gnuradio import analog
-except ImportError:
- sys.stderr.write("Error: Program requires gr-analog.\n")
- sys.exit(1)
-
-def run_test (f,Kb,bitspersymbol,K,channel,modulation,dimensionality,tot_constellation,N0,seed):
- tb = gr.top_block ()
- L = len(channel)
-
- # TX
- # this for loop is TOO slow in python!!!
- packet = [0]*(K+2*L)
- random.seed(seed)
- for i in range(len(packet)):
- packet[i] = random.randint(0, 2**bitspersymbol - 1) # random symbols
- for i in range(L): # first/last L symbols set to 0
- packet[i] = 0
- packet[len(packet)-i-1] = 0
- src = blocks.vector_source_s(packet,False)
- mod = digital.chunks_to_symbols_sf(modulation[1],modulation[0])
-
- # CHANNEL
- isi = filter.fir_filter_fff(1,channel)
- add = blockss.add_ff()
- noise = analog.noise_source_f(analog.GR_GAUSSIAN,math.sqrt(N0/2),seed)
-
- # RX
- skip = blocks.skiphead(gr.sizeof_float, L) # skip the first L samples since you know they are coming from the L zero symbols
- #metrics = trellis.metrics_f(f.O(),dimensionality,tot_constellation,digital.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for Viterbi
- #va = trellis.viterbi_s(f,K+L,-1,0) # Put -1 if the Initial/Final states are not set.
- va = trellis.viterbi_combined_fs(f,K+L,0,0,dimensionality,tot_constellation,digital.TRELLIS_EUCLIDEAN) # using viterbi_combined_fs instead of metrics_f/viterbi_s allows larger packet lengths because metrics_f is complaining for not being able to allocate large buffers. This is due to the large f.O() in this application...
- dst = blocks.vector_sink_s()
-
- tb.connect (src,mod)
- tb.connect (mod,isi,(add,0))
- tb.connect (noise,(add,1))
- #tb.connect (add,metrics)
- #tb.connect (metrics,va,dst)
- tb.connect (add,skip,va,dst)
-
- tb.run()
-
- data = dst.data()
- ntotal = len(data) - L
- nright=0
- for i in range(ntotal):
- if packet[i+L]==data[i]:
- nright=nright+1
- #else:
- #print "Error in ", i
-
- return (ntotal,ntotal-nright)
-
-
-def main(args):
- nargs = len (args)
- if nargs == 2:
- esn0_db=float(args[0])
- rep=int(args[1])
- else:
- sys.stderr.write ('usage: test_viterbi_equalization1.py Es/No_db repetitions\n')
- sys.exit (1)
-
- # system parameters
- Kb=128*16 # packet size in bits (multiple of 16)
- modulation = fsm_utils.pam4 # see fsm_utlis.py for available predefined modulations
- channel = fsm_utils.c_channel # see fsm_utlis.py for available predefined test channels
- f=trellis.fsm(len(modulation[1]),len(channel)) # generate the FSM automatically
- bitspersymbol = int(round(math.log(f.I())/math.log(2))) # bits per FSM input symbol
- K=Kb/bitspersymbol # packet size in trellis steps
-
- tot_channel = fsm_utils.make_isi_lookup(modulation,channel,True) # generate the lookup table (normalize energy to 1)
- dimensionality = tot_channel[0]
- tot_constellation = tot_channel[1]
- N0=pow(10.0,-esn0_db/10.0); # noise variance
- if len(tot_constellation)/dimensionality != f.O():
- sys.stderr.write ('Incompatible FSM output cardinality and lookup table size.\n')
- sys.exit (1)
-
- tot_s=0 # total number of transmitted shorts
- terr_s=0 # total number of shorts in error
- terr_p=0 # total number of packets in error
-
- for i in range(rep):
- (s,e)=run_test(f,Kb,bitspersymbol,K,channel,modulation,dimensionality,tot_constellation,N0,-long(666+i)) # run experiment with different seed to get different noise realizations
- tot_s=tot_s+s
- terr_s=terr_s+e
- terr_p=terr_p+(terr_s!=0)
- if ((i+1)%100==0) : # display progress
- print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
- # estimate of the (short or symbol) error rate
- print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
-
-
-
-if __name__ == '__main__':
- main (sys.argv[1:])
diff --git a/gr-trellis/gnuradio-trellis.pc.in b/gr-trellis/gnuradio-trellis.pc.in
index df7e2e2575..8ccf65b83f 100644
--- a/gr-trellis/gnuradio-trellis.pc.in
+++ b/gr-trellis/gnuradio-trellis.pc.in
@@ -4,7 +4,7 @@ libdir=@libdir@
includedir=@includedir@
Name: gnuradio-trellis
-Description: GNU Radio blocks for trellis coded modulation
+Description: GNU Radio blocks for trellis-based processing
Requires: gnuradio-runtime
Version: @LIBVER@
Libs: -L${libdir} -lgnuradio-trellis
diff --git a/gr-trellis/grc/trellis_encoder_xx.xml b/gr-trellis/grc/trellis_encoder_xx.xml
index d877d53c53..a2ad69278d 100644
--- a/gr-trellis/grc/trellis_encoder_xx.xml
+++ b/gr-trellis/grc/trellis_encoder_xx.xml
@@ -10,7 +10,9 @@
<key>trellis_encoder_xx</key>
<category>Trellis Coding</category>
<import>from gnuradio import trellis</import>
- <make>trellis.encoder_$(type)(trellis.fsm($fsm_args), $init_state)</make>
+ <make> trellis.encoder_$(type)(trellis.fsm($fsm_args), $init_state, $blocklength) if $blockwise else trellis.encoder_$(type)(trellis.fsm($fsm_args), $init_state) </make>
+ <callback>set_FSM(trellis.fsm($fsm_args))</callback>
+ <callback>set_ST($init_state)</callback>
<param>
<name>Type</name>
<key>type</key>
@@ -63,6 +65,28 @@
<value>0</value>
<type>int</type>
</param>
+ <param>
+ <name>Blockwise</name>
+ <key>blockwise</key>
+ <value>False</value>
+ <type>enum</type>
+ <hide>part</hide>
+ <option>
+ <name>On</name>
+ <key>True</key>
+ </option>
+ <option>
+ <name>Off</name>
+ <key>False</key>
+ </option>
+ </param>
+ <param>
+ <name>Block length</name>
+ <key>blocklength</key>
+ <value>0</value>
+ <type>int</type>
+ <hide>#if $blockwise() == 'True' then 'none' else 'all'#</hide>
+ </param>
<check>(isinstance(eval(""" $fsm_args """[1:-1], locals(),globals()), str) and open($fsm_args).close()) or True</check>
<sink>
<name>in</name>
diff --git a/gr-trellis/grc/trellis_metrics_x.xml b/gr-trellis/grc/trellis_metrics_x.xml
index f551bc1521..8bb978f275 100644
--- a/gr-trellis/grc/trellis_metrics_x.xml
+++ b/gr-trellis/grc/trellis_metrics_x.xml
@@ -12,6 +12,9 @@
<category>Trellis Coding</category>
<import>from gnuradio import trellis, digital</import>
<make>trellis.metrics_$(type)($card, $dim, $table, $metric_type)</make>
+ <callback>set_O($card)</callback>
+ <callback>set_D($dim)</callback>
+ <callback>set_TYPE($metric_type)</callback>
<callback>set_TABLE($table)</callback>
<param>
<name>Type</name>
diff --git a/gr-trellis/grc/trellis_pccc_decoder_combined_xx.xml b/gr-trellis/grc/trellis_pccc_decoder_combined_xx.xml
index 9bb4b034ac..ff727fbf8b 100644
--- a/gr-trellis/grc/trellis_pccc_decoder_combined_xx.xml
+++ b/gr-trellis/grc/trellis_pccc_decoder_combined_xx.xml
@@ -21,7 +21,7 @@
$dim, $table, $metric_type,
$scaling)
</make>
- <callback>set_TABLE($table)</callback>
+ <callback>set_scaling($scaling)</callback>
<param>
<name>Input Type</name>
<key>type</key>
diff --git a/gr-trellis/grc/trellis_permutation.xml b/gr-trellis/grc/trellis_permutation.xml
index bf6fc3ff15..0f118e889f 100644
--- a/gr-trellis/grc/trellis_permutation.xml
+++ b/gr-trellis/grc/trellis_permutation.xml
@@ -12,6 +12,10 @@
<category>Trellis Coding</category>
<import>from gnuradio import trellis</import>
<make>trellis.permutation($interleaver_size, $table, $syms_per_block, $type.size*$vlen)</make>
+ <callback>set_K($interleaver_size)</callback>
+ <callback>set_TABLE($table)</callback>
+ <callback>set_SYMS_PER_BLOCK($syms_per_block)</callback>
+
<param>
<name>Type</name>
<key>type</key>
diff --git a/gr-trellis/grc/trellis_sccc_decoder_combined_xx.xml b/gr-trellis/grc/trellis_sccc_decoder_combined_xx.xml
index bacc16cf5e..4947376d94 100644
--- a/gr-trellis/grc/trellis_sccc_decoder_combined_xx.xml
+++ b/gr-trellis/grc/trellis_sccc_decoder_combined_xx.xml
@@ -21,7 +21,7 @@
$dim, $table, $metric_type,
$scaling)
</make>
- <callback>set_TABLE($table)</callback>
+ <callback>set_scaling($scaling)</callback>
<param>
<name>Input Type</name>
<key>type</key>
diff --git a/gr-trellis/grc/trellis_siso_combined_f.xml b/gr-trellis/grc/trellis_siso_combined_f.xml
index 95eceeea31..542bba6d8b 100644
--- a/gr-trellis/grc/trellis_siso_combined_f.xml
+++ b/gr-trellis/grc/trellis_siso_combined_f.xml
@@ -12,6 +12,16 @@
<category>Trellis Coding</category>
<import>from gnuradio import trellis</import>
<make>trellis.siso_combined_f(trellis.fsm($fsm_args), $block_size, $init_state, $final_state, $a_post_in, $a_post_out, $siso_type, $dim, $table, $metric_type)</make>
+ <callback>set_FSM(trellis.fsm($fsm_args))</callback>
+ <callback>set_K($block_size)</callback>
+ <callback>set_S0($init_state)</callback>
+ <callback>set_SK($final_state)</callback>
+ <callback>set_POSTI($a_post_in)</callback>
+ <callback>set_POSTO($a_post_out)</callback>
+ <callback>set_SISO_TYPE($siso_type)</callback>
+ <callback>set_D($dim)</callback>
+ <callback>set_TABLE($table)</callback>
+ <callback>set_TYPE($metric_type)</callback>
<param>
<name>FSM Args</name>
<key>fsm_args</key>
@@ -101,7 +111,11 @@
</option>
</param>
<sink>
- <name>in</name>
+ <name>in_i</name>
+ <type>float</type>
+ </sink>
+ <sink>
+ <name>in_o</name>
<type>float</type>
</sink>
<source>
diff --git a/gr-trellis/grc/trellis_siso_f.xml b/gr-trellis/grc/trellis_siso_f.xml
index 67eeb27189..30849d2723 100644
--- a/gr-trellis/grc/trellis_siso_f.xml
+++ b/gr-trellis/grc/trellis_siso_f.xml
@@ -12,6 +12,13 @@
<category>Trellis Coding</category>
<import>from gnuradio import trellis</import>
<make>trellis.siso_f(trellis.fsm($fsm_args), $block_size, $init_state, $final_state, $a_post_in, $a_post_out, $siso_type)</make>
+ <callback>set_FSM(trellis.fsm($fsm_args))</callback>
+ <callback>set_K($block_size)</callback>
+ <callback>set_S0($init_state)</callback>
+ <callback>set_SK($final_state)</callback>
+ <callback>set_POSTI($a_post_in)</callback>
+ <callback>set_POSTO($a_post_out)</callback>
+ <callback>set_SISO_TYPE($siso_type)</callback>
<param>
<name>FSM Args</name>
<key>fsm_args</key>
@@ -75,7 +82,11 @@
</param>
<check>(isinstance(eval(""" $fsm_args """[1:-1], locals(),globals()), str) and open($fsm_args).close()) or True</check>
<sink>
- <name>in</name>
+ <name>priori</name>
+ <type>float</type>
+ </sink>
+ <sink>
+ <name>prioro</name>
<type>float</type>
</sink>
<source>
diff --git a/gr-trellis/grc/trellis_viterbi_combined_xx.xml b/gr-trellis/grc/trellis_viterbi_combined_xx.xml
index 81b49860a5..9c755dc524 100644
--- a/gr-trellis/grc/trellis_viterbi_combined_xx.xml
+++ b/gr-trellis/grc/trellis_viterbi_combined_xx.xml
@@ -12,7 +12,13 @@
<category>Trellis Coding</category>
<import>from gnuradio import trellis, digital</import>
<make>trellis.viterbi_combined_$(type)$(out_type)(trellis.fsm($fsm_args), $block_size, $init_state, $final_state, $dim, $table, $metric_type)</make>
- <callback>set_TABLE($table)</callback>
+ <callback>set_FSM(trellis.fsm($fsm_args))</callback>
+ <callback>set_K($block_size)</callback>
+ <callback>set_S0($init_state)</callback>
+ <callback>set_SK($final_state)</callback>
+ <callback>set_D($dim)</callback>
+ <callback>set_TABLE($table)</callback>
+ <callback>set_TYPE($metric_type)</callback>
<param>
<name>Input Type</name>
<key>type</key>
diff --git a/gr-trellis/grc/trellis_viterbi_x.xml b/gr-trellis/grc/trellis_viterbi_x.xml
index 734bb5386a..9083061e6b 100644
--- a/gr-trellis/grc/trellis_viterbi_x.xml
+++ b/gr-trellis/grc/trellis_viterbi_x.xml
@@ -12,6 +12,10 @@
<category>Trellis Coding</category>
<import>from gnuradio import trellis</import>
<make>trellis.viterbi_$(type)(trellis.fsm($fsm_args), $block_size, $init_state, $final_state)</make>
+ <callback>set_FSM(trellis.fsm($fsm_args))</callback>
+ <callback>set_K($block_size)</callback>
+ <callback>set_S0($init_state)</callback>
+ <callback>set_SK($final_state)</callback>
<param>
<name>Type</name>
<key>type</key>
diff --git a/gr-trellis/include/gnuradio/trellis/encoder_XX.h.t b/gr-trellis/include/gnuradio/trellis/encoder_XX.h.t
index 7ece5d3f21..affd62f68b 100644
--- a/gr-trellis/include/gnuradio/trellis/encoder_XX.h.t
+++ b/gr-trellis/include/gnuradio/trellis/encoder_XX.h.t
@@ -44,8 +44,14 @@ namespace gr {
static sptr make(const fsm &FSM, int ST);
+ static sptr make(const fsm &FSM, int ST, int K);
+
virtual fsm FSM() const = 0;
virtual int ST() const = 0;
+ virtual int K() const = 0;
+ virtual void set_FSM(const fsm &FSM) =0;
+ virtual void set_ST(int ST) =0;
+ virtual void set_K(int K) =0;
};
} /* namespace trellis */
diff --git a/gr-trellis/include/gnuradio/trellis/fsm.h b/gr-trellis/include/gnuradio/trellis/fsm.h
index cc8893f1e3..5ba4483b97 100644
--- a/gr-trellis/include/gnuradio/trellis/fsm.h
+++ b/gr-trellis/include/gnuradio/trellis/fsm.h
@@ -153,6 +153,16 @@ namespace gr {
* \param FSM2 second FSMS
*/
fsm(const fsm &FSM1, const fsm &FSM2);
+
+
+ /*!
+ * \brief Creates an FSMS describing the trellis of two serially concatenated FSMs.
+ *
+ * \param FSMo outer FSMS
+ * \param FSMi inner FSMS
+ * \param serial set it to true to distinguish from the previous constructor
+ */
+ fsm(const fsm &FSMo, const fsm &FSMi, bool serial);
/*!
* \brief Creates an FSMS representing n stages through the originial FSM (AKA radix-n FSM).
diff --git a/gr-trellis/include/gnuradio/trellis/metrics_X.h.t b/gr-trellis/include/gnuradio/trellis/metrics_X.h.t
index 3f650faf0e..f463c865a9 100644
--- a/gr-trellis/include/gnuradio/trellis/metrics_X.h.t
+++ b/gr-trellis/include/gnuradio/trellis/metrics_X.h.t
@@ -49,9 +49,14 @@ namespace gr {
virtual int D() const = 0;
virtual digital::trellis_metric_type_t TYPE() const = 0;
virtual std::vector<@I_TYPE@> TABLE() const = 0;
+
+ virtual void set_O(int O) = 0;
+ virtual void set_D(int D) = 0;
+ virtual void set_TYPE(digital::trellis_metric_type_t type) = 0;
virtual void set_TABLE(const std::vector<@I_TYPE@> &table) = 0;
};
+
} /* namespace trellis */
} /* namespace gr */
diff --git a/gr-trellis/include/gnuradio/trellis/permutation.h b/gr-trellis/include/gnuradio/trellis/permutation.h
index 80b9fef641..5c86f3c9a7 100644
--- a/gr-trellis/include/gnuradio/trellis/permutation.h
+++ b/gr-trellis/include/gnuradio/trellis/permutation.h
@@ -44,9 +44,14 @@ namespace gr {
int SYMS_PER_BLOCK, size_t NBYTES);
virtual int K() const = 0;
- virtual const std::vector<int> & TABLE() const = 0;
+ virtual std::vector<int> TABLE() const = 0;
virtual int SYMS_PER_BLOCK() const = 0;
virtual size_t BYTES_PER_SYMBOL() const = 0;
+
+ virtual void set_K(int K) =0;
+ virtual void set_TABLE (const std::vector<int> &table) = 0;
+ virtual void set_SYMS_PER_BLOCK(int spb) =0;
+
};
} /* namespace trellis */
diff --git a/gr-trellis/include/gnuradio/trellis/sccc_decoder_combined_XX.h.t b/gr-trellis/include/gnuradio/trellis/sccc_decoder_combined_XX.h.t
index 699de12fd8..e1f95dff1f 100644
--- a/gr-trellis/include/gnuradio/trellis/sccc_decoder_combined_XX.h.t
+++ b/gr-trellis/include/gnuradio/trellis/sccc_decoder_combined_XX.h.t
@@ -70,6 +70,7 @@ namespace gr {
virtual digital::trellis_metric_type_t METRIC_TYPE() const = 0;
virtual siso_type_t SISO_TYPE() const = 0;
virtual float scaling() const = 0;
+
virtual void set_scaling(float scaling) = 0;
};
diff --git a/gr-trellis/include/gnuradio/trellis/siso_combined_f.h b/gr-trellis/include/gnuradio/trellis/siso_combined_f.h
index 47c34ea81e..4c37b2c68d 100644
--- a/gr-trellis/include/gnuradio/trellis/siso_combined_f.h
+++ b/gr-trellis/include/gnuradio/trellis/siso_combined_f.h
@@ -60,6 +60,17 @@ namespace gr {
virtual int D() const = 0;
virtual std::vector<float> TABLE() const = 0;
virtual digital::trellis_metric_type_t TYPE() const = 0;
+
+ virtual void set_FSM(const fsm &FSM) =0;
+ virtual void set_K(int K) =0;
+ virtual void set_S0(int S0) =0;
+ virtual void set_SK(int SK) =0;
+ virtual void set_POSTI(bool POSTI) =0;
+ virtual void set_POSTO(bool POSTO) =0;
+ virtual void set_SISO_TYPE(trellis::siso_type_t type) =0;
+ virtual void set_D(int D) =0;
+ virtual void set_TABLE(const std::vector<float> &table) =0;
+ virtual void set_TYPE(digital::trellis_metric_type_t type) =0;
};
} /* namespace trellis */
diff --git a/gr-trellis/include/gnuradio/trellis/siso_f.h b/gr-trellis/include/gnuradio/trellis/siso_f.h
index ae212cb4cf..89bcba0e82 100644
--- a/gr-trellis/include/gnuradio/trellis/siso_f.h
+++ b/gr-trellis/include/gnuradio/trellis/siso_f.h
@@ -53,6 +53,14 @@ namespace gr {
virtual bool POSTI() const = 0;
virtual bool POSTO() const = 0;
virtual siso_type_t SISO_TYPE() const = 0;
+
+ virtual void set_FSM(const fsm &FSM) =0;
+ virtual void set_K(int K) =0;
+ virtual void set_S0(int S0) =0;
+ virtual void set_SK(int SK) =0;
+ virtual void set_POSTI(bool posti) =0;
+ virtual void set_POSTO(bool posto) =0;
+ virtual void set_SISO_TYPE(trellis::siso_type_t type) = 0;
};
} /* namespace trellis */
diff --git a/gr-trellis/include/gnuradio/trellis/viterbi_X.h.t b/gr-trellis/include/gnuradio/trellis/viterbi_X.h.t
index 2d72cb5e09..252ffb715d 100644
--- a/gr-trellis/include/gnuradio/trellis/viterbi_X.h.t
+++ b/gr-trellis/include/gnuradio/trellis/viterbi_X.h.t
@@ -45,10 +45,15 @@ namespace gr {
static sptr make(const fsm &FSM, int K,
int S0, int SK);
- virtual fsm FSM() const = 0;
- virtual int K() const = 0;
- virtual int S0() const = 0;
- virtual int SK() const = 0;
+ virtual fsm FSM() const = 0;
+ virtual int K() const = 0;
+ virtual int S0() const = 0;
+ virtual int SK() const = 0;
+
+ virtual void set_FSM(const fsm &FSM) =0;
+ virtual void set_K(int K) =0;
+ virtual void set_S0(int S0) =0;
+ virtual void set_SK(int SK) =0;
};
} /* namespace trellis */
diff --git a/gr-trellis/include/gnuradio/trellis/viterbi_combined_XX.h.t b/gr-trellis/include/gnuradio/trellis/viterbi_combined_XX.h.t
index 2becf8bf18..4546e95739 100644
--- a/gr-trellis/include/gnuradio/trellis/viterbi_combined_XX.h.t
+++ b/gr-trellis/include/gnuradio/trellis/viterbi_combined_XX.h.t
@@ -50,12 +50,19 @@ namespace gr {
virtual fsm FSM() const = 0;
virtual int K() const = 0;
- virtual int S0() const = 0;
+ virtual int S0() const = 0;
virtual int SK() const = 0;
virtual int D() const = 0;
virtual std::vector<@I_TYPE@> TABLE() const = 0;
virtual digital::trellis_metric_type_t TYPE() const = 0;
+
+ virtual void set_FSM(const fsm &FSM) =0;
+ virtual void set_K(int K) =0;
+ virtual void set_S0(int S0) =0;
+ virtual void set_SK(int SK) =0;
+ virtual void set_D(int D) =0;
virtual void set_TABLE (const std::vector<@I_TYPE@> &table) = 0;
+ virtual void set_TYPE(digital::trellis_metric_type_t type) = 0;
};
} /* namespace trellis */
diff --git a/gr-trellis/lib/calc_metric.cc b/gr-trellis/lib/calc_metric.cc
index b95899940a..bdbb13ea08 100644
--- a/gr-trellis/lib/calc_metric.cc
+++ b/gr-trellis/lib/calc_metric.cc
@@ -73,19 +73,17 @@ namespace gr {
}
template
- void calc_metric<short>(int O, int D, const std::vector<short> &TABLE, const short *input,
- float *metric, digital::trellis_metric_type_t type);
+ void calc_metric<char>(int O, int D, const std::vector<char> &TABLE, const char *input, float *metric, digital::trellis_metric_type_t type);
template
- void calc_metric<int>(int O, int D, const std::vector<int> &TABLE, const int *input,
- float *metric, digital::trellis_metric_type_t type);
+ void calc_metric<short>(int O, int D, const std::vector<short> &TABLE, const short *input, float *metric, digital::trellis_metric_type_t type);
- template
- void calc_metric<float>(int O, int D, const std::vector<float> &TABLE, const float *input,
- float *metric, digital::trellis_metric_type_t type);
+ template void calc_metric<int>(int O, int D, const std::vector<int> &TABLE, const int *input, float *metric, digital::trellis_metric_type_t type);
- void calc_metric(int O, int D, const std::vector<short> &TABLE, const short *input,
- float *metric, digital::trellis_metric_type_t type)
+ template void calc_metric<float>(int O, int D, const std::vector<float> &TABLE, const float *input, float *metric, digital::trellis_metric_type_t type);
+
+ /*
+ void calc_metric(int O, int D, const std::vector<short> &TABLE, const short *input, float *metric, digital::trellis_metric_type_t type)
{
float minm = FLT_MAX;
int minmi = 0;
@@ -124,7 +122,6 @@ namespace gr {
}
}
- /*
void calc_metric(int O, int D, const std::vector<int> &TABLE, const int *input,
float *metric, digital::trellis_metric_type_t type)
{
diff --git a/gr-trellis/lib/core_algorithms.cc b/gr-trellis/lib/core_algorithms.cc
index a8a0174551..b26ee331f2 100644
--- a/gr-trellis/lib/core_algorithms.cc
+++ b/gr-trellis/lib/core_algorithms.cc
@@ -215,6 +215,19 @@ namespace gr {
//---------------
template void
+ viterbi_algorithm_combined<char,unsigned char>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<char> &TABLE,
+ digital::trellis_metric_type_t TYPE,
+ const char *in, unsigned char *out);
+
+ template void
viterbi_algorithm_combined<short,unsigned char>(int I, int S, int O,
const std::vector<int> &NS,
const std::vector<int> &OS,
@@ -269,6 +282,19 @@ namespace gr {
//---------------
template void
+ viterbi_algorithm_combined<char,short>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<char> &TABLE,
+ digital::trellis_metric_type_t TYPE,
+ const char *in, short *out);
+
+ template void
viterbi_algorithm_combined<short,short>(int I, int S, int O,
const std::vector<int> &NS,
const std::vector<int> &OS,
@@ -323,6 +349,19 @@ namespace gr {
//--------------
template void
+ viterbi_algorithm_combined<char,int>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<char> &TABLE,
+ digital::trellis_metric_type_t TYPE,
+ const char *in, int *out);
+
+ template void
viterbi_algorithm_combined<short,int>(int I, int S, int O,
const std::vector<int> &NS,
const std::vector<int> &OS,
@@ -1177,17 +1216,17 @@ namespace gr {
for(int k=0;k<blocklength;k++) {
//std::cout << k << std::endl;
for(int i=0;i<FSM1.O();i++) {
- float x=cprioro[k*FSM1.O()*FSM2.O()+i*FSM1.O()+0];
+ float x=cprioro[k*O+i*FSM2.O()+0];
for(int j=1;j<FSM2.O();j++)
- x = (*p2mymin)(x,cprioro[k*FSM1.O()*FSM2.O()+i*FSM1.O()+j]);
+ x = (*p2mymin)(x,cprioro[k*O+i*FSM2.O()+j]);
prioro1[k*FSM1.O()+i]=x;
//std::cout << prioro1[k*FSM1.O()+i] << ", ";
}
//std::cout << std::endl;
for(int i=0;i<FSM2.O();i++) {
- float x=cprioro[k*FSM1.O()*FSM2.O()+0*FSM1.O()+i];
+ float x=cprioro[k*O+0*FSM2.O()+i];
for(int j=1;j<FSM1.O();j++)
- x = (*p2mymin)(x,cprioro[k*FSM1.O()*FSM2.O()+j*FSM1.O()+i]);
+ x = (*p2mymin)(x,cprioro[k*O+j*FSM2.O()+i]);
prioro2[k*FSM2.O()+i]=x;
}
}
diff --git a/gr-trellis/lib/encoder_XX_impl.cc.t b/gr-trellis/lib/encoder_XX_impl.cc.t
index 4b11e3c06d..3a004a2f94 100644
--- a/gr-trellis/lib/encoder_XX_impl.cc.t
+++ b/gr-trellis/lib/encoder_XX_impl.cc.t
@@ -37,18 +37,45 @@ namespace gr {
@BASE_NAME@::make(const fsm &FSM, int ST)
{
return gnuradio::get_initial_sptr
- (new @IMPL_NAME@(FSM,ST));
+ (new @IMPL_NAME@(FSM,ST,0,false));
}
- @IMPL_NAME@::@IMPL_NAME@(const fsm &FSM, int ST)
+ @BASE_NAME@::sptr
+ @BASE_NAME@::make(const fsm &FSM, int ST, int K)
+ {
+ return gnuradio::get_initial_sptr
+ (new @IMPL_NAME@(FSM,ST,K,true));
+ }
+
+ @IMPL_NAME@::@IMPL_NAME@(const fsm &FSM, int ST, int K, bool B)
: sync_block("@BASE_NAME@",
- io_signature::make(1, -1, sizeof(@I_TYPE@)),
- io_signature::make(1, -1, sizeof(@O_TYPE@))),
+ io_signature::make(1, 1, sizeof(@I_TYPE@)),
+ io_signature::make(1, 1, sizeof(@O_TYPE@))),
d_FSM(FSM),
- d_ST(ST)
+ d_ST(ST),
+ d_K(K),
+ d_B(B)
{
}
+ void @IMPL_NAME@::set_FSM(const fsm &FSM)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_FSM = FSM;
+ }
+
+ void @IMPL_NAME@::set_ST(int ST)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_ST = ST;
+ }
+
+ void @IMPL_NAME@::set_K(int K)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_K = K;
+ }
+
@IMPL_NAME@::~@IMPL_NAME@()
{
}
@@ -58,25 +85,34 @@ namespace gr {
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
+ gr::thread::scoped_lock guard(d_setlock);
int ST_tmp = 0;
- int nstreams = input_items.size();
- for(int m=0;m<nstreams;m++) {
- const @I_TYPE@ *in = (const @I_TYPE@*)input_items[m];
- @O_TYPE@ *out = (@O_TYPE@ *) output_items[m];
- ST_tmp = d_ST;
-
- // per stream processing
- for(int i = 0; i < noutput_items; i++) {
- out[i] = (@O_TYPE@)d_FSM.OS()[ST_tmp*d_FSM.I()+in[i]]; // direction of time?
- ST_tmp = (int)d_FSM.NS()[ST_tmp*d_FSM.I()+in[i]];
- }
- // end per stream processing
- }
- d_ST = ST_tmp;
-
- return noutput_items;
- }
+ if (d_B){ // blockwise operation
+ int nblocks = noutput_items /d_K;
+ const @I_TYPE@ *in = (const @I_TYPE@*)input_items[0];
+ @O_TYPE@ *out = (@O_TYPE@ *) output_items[0];
+ for(int n = 0; n < nblocks; n++) {
+ ST_tmp = d_ST;
+ for(int i = 0; i < d_K; i++) {
+ out[n*d_K+i] = (@O_TYPE@)d_FSM.OS()[ST_tmp*d_FSM.I()+in[n*d_K+i]];
+ ST_tmp = (int)d_FSM.NS()[ST_tmp*d_FSM.I()+in[n*d_K+i]];
+ }
+ }
+ return nblocks*d_K;
+ } // end blockwise operation
+ else{ // streaming operation
+ const @I_TYPE@ *in = (const @I_TYPE@*)input_items[0];
+ @O_TYPE@ *out = (@O_TYPE@ *) output_items[0];
+ ST_tmp = d_ST;
+ for(int i = 0; i < noutput_items; i++) {
+ out[i] = (@O_TYPE@)d_FSM.OS()[ST_tmp*d_FSM.I()+in[i]];
+ ST_tmp = (int)d_FSM.NS()[ST_tmp*d_FSM.I()+in[i]];
+ }
+ d_ST = ST_tmp;
+ return noutput_items;
+ } // end streaming operation
+ }
} /* namespace trellis */
} /* namespace gr */
diff --git a/gr-trellis/lib/encoder_XX_impl.h.t b/gr-trellis/lib/encoder_XX_impl.h.t
index ec2f82611e..2b0ff31f4d 100644
--- a/gr-trellis/lib/encoder_XX_impl.h.t
+++ b/gr-trellis/lib/encoder_XX_impl.h.t
@@ -35,14 +35,20 @@ namespace gr {
private:
fsm d_FSM;
int d_ST;
+ int d_K;
+ bool d_B;
+
public:
- @IMPL_NAME@(const fsm &FSM, int ST);
+ @IMPL_NAME@(const fsm &FSM, int ST, int K, bool B);
~@IMPL_NAME@();
- fsm FSM() const { return d_FSM; }
- int ST() const { return d_ST; }
-
+ fsm FSM() const { return d_FSM;; }
+ int ST() const { return d_ST; }
+ int K() const { return d_K; }
+ void set_FSM(const fsm &FSM);
+ void set_ST(int ST);
+ void set_K(int K);
int work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
diff --git a/gr-trellis/lib/fsm.cc b/gr-trellis/lib/fsm.cc
index 20eeed5c25..4e57949f5e 100644
--- a/gr-trellis/lib/fsm.cc
+++ b/gr-trellis/lib/fsm.cc
@@ -313,6 +313,54 @@ namespace gr {
generate_TM();
}
+
+ //######################################################################
+ //# Automatically generate an FSM specification describing the
+ //# the joint trellis of two serially concatenated fsms.
+ //######################################################################
+ fsm::fsm(const fsm &FSMo, const fsm &FSMi, bool serial)
+ {
+ if(serial==false || FSMo.O()!=FSMi.I()) {
+ d_I=0;
+ d_S=0;
+ d_O=0;
+ d_NS.resize(0);
+ d_OS.resize(0);
+ d_PS.resize(0);
+ d_PI.resize(0);
+ d_TMi.resize(0);
+ d_TMl.resize(0);
+ return;
+ }
+
+ d_I=FSMo.I();
+ d_S=FSMo.S()*FSMi.S();
+ d_O=FSMi.O();
+
+ d_NS.resize(d_I*d_S);
+ d_OS.resize(d_I*d_S);
+
+ for(int s=0;s<d_S;s++) {
+ for(int i=0;i<d_I;i++) {
+ int so=s/FSMi.S();
+ int si=s%FSMi.S();
+ int oo=FSMo.OS()[so * FSMo.I() + i];
+ int oi=FSMi.OS()[si * FSMi.I() + oo];
+ d_NS[s*d_I+i] = FSMo.NS()[so * FSMo.I() + i] * FSMo.S() + FSMi.NS()[si * FSMi.I() + oo];
+ d_OS[s*d_I+i] = oi;
+ }
+ }
+
+ generate_PS_PI();
+ generate_TM();
+ }
+
+
+
+
+
+
+
//######################################################################
//# Generate a new FSM representing n stages through the original FSM
//# AKA radix-n FSM
diff --git a/gr-trellis/lib/metrics_X_impl.cc.t b/gr-trellis/lib/metrics_X_impl.cc.t
index 499bd8b9cd..5e74e4b2fc 100644
--- a/gr-trellis/lib/metrics_X_impl.cc.t
+++ b/gr-trellis/lib/metrics_X_impl.cc.t
@@ -54,16 +54,40 @@ namespace gr {
set_output_multiple ((int)d_O);
}
- @IMPL_NAME@::~@IMPL_NAME@()
+ void @IMPL_NAME@::set_O(int O)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_O = O;
+ set_relative_rate (1.0 * d_O / ((double) d_D));
+ set_output_multiple ((int)d_O);
+ }
+
+ void @IMPL_NAME@::set_D(int D)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_D = D;
+ set_relative_rate (1.0 * d_O / ((double) d_D));
+ }
+
+ void
+ @IMPL_NAME@::set_TYPE(digital::trellis_metric_type_t type)
{
+ gr::thread::scoped_lock guard(d_setlock);
+ d_TYPE = type;
}
void
@IMPL_NAME@::set_TABLE(const std::vector<@I_TYPE@> &table)
{
+ gr::thread::scoped_lock guard(d_setlock);
d_TABLE = table;
}
+ @IMPL_NAME@::~@IMPL_NAME@()
+ {
+ }
+
+
void
@IMPL_NAME@::forecast(int noutput_items, gr_vector_int &ninput_items_required)
{
@@ -79,6 +103,7 @@ namespace gr {
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
+ gr::thread::scoped_lock guard(d_setlock);
int nstreams = input_items.size();
for(int m = 0; m < nstreams; m++) {
diff --git a/gr-trellis/lib/metrics_X_impl.h.t b/gr-trellis/lib/metrics_X_impl.h.t
index 2b4481fdb1..9323ae4645 100644
--- a/gr-trellis/lib/metrics_X_impl.h.t
+++ b/gr-trellis/lib/metrics_X_impl.h.t
@@ -47,6 +47,10 @@ namespace gr {
int D() const { return d_D; }
digital::trellis_metric_type_t TYPE() const { return d_TYPE; }
std::vector<@I_TYPE@> TABLE() const { return d_TABLE; }
+
+ void set_O(int O);
+ void set_D(int D);
+ void set_TYPE(digital::trellis_metric_type_t type);
void set_TABLE(const std::vector<@I_TYPE@> &table);
void forecast(int noutput_items,
diff --git a/gr-trellis/lib/pccc_decoder_combined_XX_impl.cc.t b/gr-trellis/lib/pccc_decoder_combined_XX_impl.cc.t
index 15ea3ceecb..5b3cdeeb62 100644
--- a/gr-trellis/lib/pccc_decoder_combined_XX_impl.cc.t
+++ b/gr-trellis/lib/pccc_decoder_combined_XX_impl.cc.t
@@ -90,6 +90,7 @@ namespace gr {
void
@IMPL_NAME@::set_scaling(float scaling)
{
+ gr::thread::scoped_lock guard(d_setlock);
d_scaling = scaling;
}
@@ -109,6 +110,7 @@ namespace gr {
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
+ gr::thread::scoped_lock guard(d_setlock);
int nblocks = noutput_items / d_blocklength;
float (*p2min)(float, float) = NULL;
diff --git a/gr-trellis/lib/pccc_encoder_XX_impl.cc.t b/gr-trellis/lib/pccc_encoder_XX_impl.cc.t
index 119bff6ddb..8fd143ca9d 100644
--- a/gr-trellis/lib/pccc_encoder_XX_impl.cc.t
+++ b/gr-trellis/lib/pccc_encoder_XX_impl.cc.t
@@ -81,7 +81,7 @@ namespace gr {
ST1_tmp = (int) d_FSM1.NS()[ST1_tmp*d_FSM1.I()+in[i]];
int o2 = d_FSM2.OS()[ST2_tmp*d_FSM2.I()+in[k]];
ST2_tmp = (int) d_FSM2.NS()[ST2_tmp*d_FSM2.I()+in[k]];
- out[i] = (@O_TYPE@) (o1*d_FSM1.O() + o2);
+ out[i] = (@O_TYPE@) (o1*d_FSM2.O() + o2);
}
}
return noutput_items;
diff --git a/gr-trellis/lib/permutation_impl.cc b/gr-trellis/lib/permutation_impl.cc
index 06bba1e11f..2fe0ea8cb8 100644
--- a/gr-trellis/lib/permutation_impl.cc
+++ b/gr-trellis/lib/permutation_impl.cc
@@ -49,10 +49,30 @@ namespace gr {
d_SYMS_PER_BLOCK(SYMS_PER_BLOCK),
d_BYTES_PER_SYMBOL(BYTES_PER_SYMBOL)
{
- set_output_multiple(d_K*SYMS_PER_BLOCK);
+ set_output_multiple(d_K*d_SYMS_PER_BLOCK);
//std::cout << d_K << "\n";
}
+ void permutation_impl::set_K(int K)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_K=K;
+ set_output_multiple(d_K*d_SYMS_PER_BLOCK);
+ }
+
+ void permutation_impl::set_TABLE (const std::vector<int> &table)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_TABLE = table;
+ }
+
+ void permutation_impl::set_SYMS_PER_BLOCK(int spb)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_SYMS_PER_BLOCK=spb;
+ set_output_multiple(d_K*d_SYMS_PER_BLOCK);
+ }
+
permutation_impl::~permutation_impl()
{
}
@@ -62,6 +82,7 @@ namespace gr {
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
+ gr::thread::scoped_lock guard(d_setlock);
int nstreams = input_items.size();
for(int m=0;m<nstreams;m++) {
diff --git a/gr-trellis/lib/permutation_impl.h b/gr-trellis/lib/permutation_impl.h
index 2c7b28d62f..e013e52a20 100644
--- a/gr-trellis/lib/permutation_impl.h
+++ b/gr-trellis/lib/permutation_impl.h
@@ -43,10 +43,14 @@ namespace gr {
~permutation_impl();
int K() const { return d_K; }
- const std::vector<int> & TABLE() const { return d_TABLE; }
+ std::vector<int> TABLE() const { return d_TABLE; }
int SYMS_PER_BLOCK() const { return d_SYMS_PER_BLOCK; }
size_t BYTES_PER_SYMBOL() const { return d_BYTES_PER_SYMBOL; }
+ void set_K(int K) ;
+ void set_TABLE (const std::vector<int> &table);
+ void set_SYMS_PER_BLOCK(int spb) ;
+
int work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
diff --git a/gr-trellis/lib/sccc_decoder_combined_XX_impl.cc.t b/gr-trellis/lib/sccc_decoder_combined_XX_impl.cc.t
index 4acc560175..f66b1f37e7 100644
--- a/gr-trellis/lib/sccc_decoder_combined_XX_impl.cc.t
+++ b/gr-trellis/lib/sccc_decoder_combined_XX_impl.cc.t
@@ -89,6 +89,7 @@ namespace gr {
void
@IMPL_NAME@::set_scaling(float scaling)
{
+ gr::thread::scoped_lock guard(d_setlock);
d_scaling = scaling;
}
@@ -108,6 +109,7 @@ namespace gr {
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
+ gr::thread::scoped_lock guard(d_setlock);
int nblocks = noutput_items / d_blocklength;
float (*p2min)(float, float) = NULL;
diff --git a/gr-trellis/lib/siso_combined_f_impl.cc b/gr-trellis/lib/siso_combined_f_impl.cc
index d30f5cc4bb..3b89684bf0 100644
--- a/gr-trellis/lib/siso_combined_f_impl.cc
+++ b/gr-trellis/lib/siso_combined_f_impl.cc
@@ -48,23 +48,9 @@ namespace gr {
SISO_TYPE, D, TABLE, TYPE));
}
- siso_combined_f_impl::siso_combined_f_impl(const fsm &FSM, int K,
- int S0, int SK,
- bool POSTI, bool POSTO,
- siso_type_t SISO_TYPE,
- int D, const std::vector<float> &TABLE,
- digital::trellis_metric_type_t TYPE)
- : block("siso_combined_f",
- io_signature::make(1, -1, sizeof(float)),
- io_signature::make(1, -1, sizeof(float))),
- d_FSM(FSM), d_K(K), d_S0(S0), d_SK(SK),
- d_POSTI(POSTI), d_POSTO(POSTO),
- d_SISO_TYPE(SISO_TYPE),
- d_D(D), d_TABLE(TABLE), d_TYPE(TYPE)//,
- //d_alpha(FSM.S()*(K+1)),
- //d_beta(FSM.S()*(K+1))
+ void siso_combined_f_impl::recalculate()
{
- int multiple;
+ int multiple;
if(d_POSTI && d_POSTO)
multiple = d_FSM.I()+d_FSM.O();
else if(d_POSTI)
@@ -74,7 +60,6 @@ namespace gr {
else
throw std::runtime_error ("Not both POSTI and POSTO can be false.");
- //printf("constructor: Multiple = %d\n",multiple);
set_output_multiple(d_K*multiple);
//what is the meaning of relative rate for a block with 2 inputs?
@@ -84,9 +69,94 @@ namespace gr {
//set_relative_rate ( multiple / ((double) d_FSM.O()) );
// I am tempted to automate like this
if(d_FSM.I() <= d_D)
- set_relative_rate(multiple / ((double)d_D));
+ set_relative_rate(multiple / ((double)d_D));
else
- set_relative_rate(multiple / ((double)d_FSM.I()));
+ set_relative_rate(multiple / ((double)d_FSM.I()));
+ }
+
+
+ siso_combined_f_impl::siso_combined_f_impl(const fsm &FSM, int K,
+ int S0, int SK,
+ bool POSTI, bool POSTO,
+ siso_type_t SISO_TYPE,
+ int D, const std::vector<float> &TABLE,
+ digital::trellis_metric_type_t TYPE)
+ : block("siso_combined_f",
+ io_signature::make(1, -1, sizeof(float)),
+ io_signature::make(1, -1, sizeof(float))),
+ d_FSM(FSM), d_K(K), d_S0(S0), d_SK(SK),
+ d_POSTI(POSTI), d_POSTO(POSTO),
+ d_SISO_TYPE(SISO_TYPE),
+ d_D(D), d_TABLE(TABLE), d_TYPE(TYPE)//,
+ //d_alpha(FSM.S()*(K+1)),
+ //d_beta(FSM.S()*(K+1))
+ {
+ recalculate();
+ }
+
+ void siso_combined_f_impl::set_FSM(const fsm &FSM)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_FSM=FSM;
+ recalculate();
+ }
+
+ void siso_combined_f_impl::set_K(int K)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_K=K;
+ recalculate();
+ }
+
+ void siso_combined_f_impl::set_POSTI(bool POSTI)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_POSTI = POSTI;
+ recalculate();
+ }
+
+ void siso_combined_f_impl::set_POSTO(bool POSTO)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_POSTO = POSTO;
+ recalculate();
+ }
+
+ void siso_combined_f_impl::set_D(int D)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_D=D;
+ recalculate();
+ }
+
+ void siso_combined_f_impl::set_S0(int S0)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_S0 = S0;
+ }
+
+ void siso_combined_f_impl::set_SK(int SK)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_SK = SK;
+ }
+
+ void siso_combined_f_impl::set_SISO_TYPE(trellis::siso_type_t type)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_SISO_TYPE = type;
+ }
+
+ void siso_combined_f_impl::set_TABLE(const std::vector<float> &table)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_TABLE = table;
+ }
+
+ void siso_combined_f_impl::set_TYPE(digital::trellis_metric_type_t type)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_TYPE = type;
}
siso_combined_f_impl::~siso_combined_f_impl()
@@ -126,6 +196,7 @@ namespace gr {
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
+ gr::thread::scoped_lock guard(d_setlock);
int nstreams = output_items.size();
//printf("general_work:Streams: %d\n",nstreams);
diff --git a/gr-trellis/lib/siso_combined_f_impl.h b/gr-trellis/lib/siso_combined_f_impl.h
index 5035a0a83d..93e9aa87d2 100644
--- a/gr-trellis/lib/siso_combined_f_impl.h
+++ b/gr-trellis/lib/siso_combined_f_impl.h
@@ -41,6 +41,7 @@ namespace gr {
int d_D;
std::vector<float> d_TABLE;
digital::trellis_metric_type_t d_TYPE;
+ void recalculate();
//std::vector<float> d_alpha;
//std::vector<float> d_beta;
@@ -64,6 +65,17 @@ namespace gr {
std::vector<float> TABLE() const { return d_TABLE; }
digital::trellis_metric_type_t TYPE() const { return d_TYPE; }
+ void set_FSM(const fsm &FSM);
+ void set_K(int K);
+ void set_S0(int S0);
+ void set_SK(int SK);
+ void set_POSTI(bool POSTI);
+ void set_POSTO(bool POSTO);
+ void set_SISO_TYPE(trellis::siso_type_t type);
+ void set_D(int D);
+ void set_TABLE(const std::vector<float> &table);
+ void set_TYPE(digital::trellis_metric_type_t type);
+
void forecast(int noutput_items,
gr_vector_int &ninput_items_required);
diff --git a/gr-trellis/lib/siso_f_impl.cc b/gr-trellis/lib/siso_f_impl.cc
index d699cecaec..2af5a21710 100644
--- a/gr-trellis/lib/siso_f_impl.cc
+++ b/gr-trellis/lib/siso_f_impl.cc
@@ -45,19 +45,8 @@ namespace gr {
(new siso_f_impl(FSM, K, S0, SK, POSTI, POSTO, SISO_TYPE));
}
- siso_f_impl::siso_f_impl(const fsm &FSM, int K,
- int S0, int SK,
- bool POSTI, bool POSTO,
- siso_type_t SISO_TYPE)
- : block("siso_f",
- io_signature::make(1, -1, sizeof(float)),
- io_signature::make(1, -1, sizeof(float))),
- d_FSM(FSM), d_K(K),
- d_S0(S0),d_SK(SK),
- d_POSTI(POSTI), d_POSTO(POSTO),
- d_SISO_TYPE(SISO_TYPE)//,
- //d_alpha(FSM.S()*(K+1)),
- //d_beta(FSM.S()*(K+1))
+
+ void siso_f_impl::recalculate()
{
int multiple;
if(d_POSTI && d_POSTO)
@@ -69,7 +58,6 @@ namespace gr {
else
throw std::runtime_error ("Not both POSTI and POSTO can be false.");
- //printf("constructor: Multiple = %d\n",multiple);
set_output_multiple (d_K*multiple);
//what is the meaning of relative rate for a block with 2 inputs?
@@ -84,6 +72,69 @@ namespace gr {
set_relative_rate(multiple / ((double) d_FSM.I()));
}
+ siso_f_impl::siso_f_impl(const fsm &FSM, int K,
+ int S0, int SK,
+ bool POSTI, bool POSTO,
+ siso_type_t SISO_TYPE)
+ : block("siso_f",
+ io_signature::make(1, -1, sizeof(float)),
+ io_signature::make(1, -1, sizeof(float))),
+ d_FSM(FSM), d_K(K),
+ d_S0(S0),d_SK(SK),
+ d_POSTI(POSTI), d_POSTO(POSTO),
+ d_SISO_TYPE(SISO_TYPE)//,
+ //d_alpha(FSM.S()*(K+1)),
+ //d_beta(FSM.S()*(K+1))
+ {
+ recalculate();
+ }
+
+ void siso_f_impl::set_FSM(const fsm &FSM)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_FSM=FSM;
+ recalculate();
+ }
+
+ void siso_f_impl::set_K(int K)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_K=K;
+ recalculate();
+ }
+
+ void siso_f_impl::set_POSTI(bool POSTI)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_POSTI = POSTI;
+ recalculate();
+ }
+
+ void siso_f_impl::set_POSTO(bool POSTO)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_POSTO = POSTO;
+ recalculate();
+ }
+
+ void siso_f_impl::set_S0(int S0)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_S0 = S0;
+ }
+
+ void siso_f_impl::set_SK(int SK)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_SK = SK;
+ }
+
+ void siso_f_impl::set_SISO_TYPE(trellis::siso_type_t type)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_SISO_TYPE = type;
+ }
+
siso_f_impl::~siso_f_impl()
{
}
@@ -119,6 +170,7 @@ namespace gr {
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
+ gr::thread::scoped_lock guard(d_setlock);
int nstreams = output_items.size();
//printf("general_work:Streams: %d\n",nstreams);
int multiple;
diff --git a/gr-trellis/lib/siso_f_impl.h b/gr-trellis/lib/siso_f_impl.h
index ca8f623aaf..f92616bf0a 100644
--- a/gr-trellis/lib/siso_f_impl.h
+++ b/gr-trellis/lib/siso_f_impl.h
@@ -42,6 +42,7 @@ namespace gr {
bool d_POSTI;
bool d_POSTO;
siso_type_t d_SISO_TYPE;
+ void recalculate();
//std::vector<float> d_alpha;
//std::vector<float> d_beta;
@@ -60,6 +61,14 @@ namespace gr {
bool POSTO() const { return d_POSTO; }
siso_type_t SISO_TYPE() const { return d_SISO_TYPE; }
+ void set_FSM(const fsm &FSM);
+ void set_K(int K);
+ void set_S0(int S0);
+ void set_SK(int SK);
+ void set_POSTI(bool POSTI);
+ void set_POSTO(bool POSTO);
+ void set_SISO_TYPE(trellis::siso_type_t type);
+
void forecast(int noutput_items,
gr_vector_int &ninput_items_required);
diff --git a/gr-trellis/lib/viterbi_X_impl.cc.t b/gr-trellis/lib/viterbi_X_impl.cc.t
index 247424b3f3..1d4864596e 100644
--- a/gr-trellis/lib/viterbi_X_impl.cc.t
+++ b/gr-trellis/lib/viterbi_X_impl.cc.t
@@ -55,6 +55,32 @@ namespace gr {
set_output_multiple(d_K);
}
+ void @IMPL_NAME@::set_FSM(const fsm &FSM)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_FSM = FSM;
+ set_relative_rate(1.0 / ((double)d_FSM.O()));
+ }
+
+ void @IMPL_NAME@::set_K(int K)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_K = K;
+ set_output_multiple(d_K);
+ }
+
+ void @IMPL_NAME@::set_S0(int S0)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_S0 = S0;
+ }
+
+ void @IMPL_NAME@::set_SK(int SK)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_SK = SK;
+ }
+
@IMPL_NAME@::~@IMPL_NAME@()
{
}
@@ -76,6 +102,7 @@ namespace gr {
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
+ gr::thread::scoped_lock guard(d_setlock);
int nstreams = input_items.size();
int nblocks = noutput_items / d_K;
diff --git a/gr-trellis/lib/viterbi_X_impl.h.t b/gr-trellis/lib/viterbi_X_impl.h.t
index b9554e8c39..1479ad5a3f 100644
--- a/gr-trellis/lib/viterbi_X_impl.h.t
+++ b/gr-trellis/lib/viterbi_X_impl.h.t
@@ -44,11 +44,15 @@ namespace gr {
int S0, int SK);
~@IMPL_NAME@();
- fsm FSM() const { return d_FSM; }
- int K() const { return d_K; }
- int S0() const { return d_S0; }
- int SK() const { return d_SK; }
+ fsm FSM() const { return d_FSM; }
+ int K() const { return d_K; }
+ int S0() const { return d_S0; }
+ int SK() const { return d_SK; }
+ void set_FSM(const fsm &FSM);
+ void set_K(int K);
+ void set_S0(int S0);
+ void set_SK(int SK);
//std::vector<int> trace () const { return d_trace; }
void forecast(int noutput_items,
diff --git a/gr-trellis/lib/viterbi_combined_XX_impl.cc.t b/gr-trellis/lib/viterbi_combined_XX_impl.cc.t
index c7cf10e567..722708bcd2 100644
--- a/gr-trellis/lib/viterbi_combined_XX_impl.cc.t
+++ b/gr-trellis/lib/viterbi_combined_XX_impl.cc.t
@@ -60,16 +60,58 @@ namespace gr {
set_output_multiple(d_K);
}
- @IMPL_NAME@::~@IMPL_NAME@()
+ void
+ @IMPL_NAME@::set_K(int K)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_K = K;
+ set_output_multiple(d_K);
+ }
+
+ void
+ @IMPL_NAME@::set_D(int D)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_D = D;
+ set_relative_rate(1.0 / ((double)d_D));
+ }
+
+ void @IMPL_NAME@::set_FSM(const fsm &FSM)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_FSM = FSM;
+ }
+
+ void @IMPL_NAME@::set_S0(int S0)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_S0 = S0;
+ }
+
+ void @IMPL_NAME@::set_SK(int SK)
+ {
+ gr::thread::scoped_lock guard(d_setlock);
+ d_SK = SK;
+ }
+
+ void
+ @IMPL_NAME@::set_TYPE(digital::trellis_metric_type_t type)
{
+ gr::thread::scoped_lock guard(d_setlock);
+ d_TYPE = type;
}
void
@IMPL_NAME@::set_TABLE(const std::vector<@I_TYPE@> &table)
{
+ gr::thread::scoped_lock guard(d_setlock);
d_TABLE = table;
}
+ @IMPL_NAME@::~@IMPL_NAME@()
+ {
+ }
+
void
@IMPL_NAME@::forecast(int noutput_items,
gr_vector_int &ninput_items_required)
@@ -87,6 +129,7 @@ namespace gr {
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
+ gr::thread::scoped_lock guard(d_setlock);
int nstreams = input_items.size();
int nblocks = noutput_items / d_K;
diff --git a/gr-trellis/lib/viterbi_combined_XX_impl.h.t b/gr-trellis/lib/viterbi_combined_XX_impl.h.t
index 199e8c8e88..788e609895 100644
--- a/gr-trellis/lib/viterbi_combined_XX_impl.h.t
+++ b/gr-trellis/lib/viterbi_combined_XX_impl.h.t
@@ -49,15 +49,22 @@ namespace gr {
digital::trellis_metric_type_t TYPE);
~@IMPL_NAME@();
- fsm FSM() const { return d_FSM; }
- int K() const { return d_K; }
- int S0() const { return d_S0; }
- int SK() const { return d_SK; }
- int D() const { return d_D; }
+ fsm FSM() const { return d_FSM; }
+ int K() const { return d_K; }
+ int S0() const { return d_S0; }
+ int SK() const { return d_SK; }
+ int D() const { return d_D; }
std::vector<@I_TYPE@> TABLE() const { return d_TABLE; }
digital::trellis_metric_type_t TYPE() const { return d_TYPE; }
//std::vector<int> trace() const { return d_trace; }
+
+ void set_FSM(const fsm &FSM);
+ void set_K(int K);
+ void set_S0(int S0);
+ void set_SK(int SK);
+ void set_D(int D);
void set_TABLE(const std::vector<@I_TYPE@> &table);
+ void set_TYPE(digital::trellis_metric_type_t type);
void forecast(int noutput_items,
gr_vector_int &ninput_items_required);
diff --git a/gr-trellis/python/trellis/CMakeLists.txt b/gr-trellis/python/trellis/CMakeLists.txt
index b4223af935..5cfe927412 100644
--- a/gr-trellis/python/trellis/CMakeLists.txt
+++ b/gr-trellis/python/trellis/CMakeLists.txt
@@ -25,6 +25,7 @@ include(GrPython)
GR_PYTHON_INSTALL(
FILES
__init__.py
+ fsm_utils.py
DESTINATION ${GR_PYTHON_DIR}/gnuradio/trellis
COMPONENT "trellis_python"
)
diff --git a/gr-trellis/python/trellis/__init__.py b/gr-trellis/python/trellis/__init__.py
index 6c6d80ecdf..662aa58197 100644
--- a/gr-trellis/python/trellis/__init__.py
+++ b/gr-trellis/python/trellis/__init__.py
@@ -31,3 +31,6 @@ except ImportError:
dirname, filename = os.path.split(os.path.abspath(__file__))
__path__.append(os.path.join(dirname, "..", "..", "swig"))
from trellis_swig import *
+
+# import any pure python here
+import fsm_utils
diff --git a/gr-trellis/examples/python/fsm_utils.py b/gr-trellis/python/trellis/fsm_utils.py
index 06855ea775..72aa1d3660 100755
--- a/gr-trellis/examples/python/fsm_utils.py
+++ b/gr-trellis/python/trellis/fsm_utils.py
@@ -27,7 +27,7 @@ import sys
import operator
import numpy
-from gnuradio import trellis
+#from gnuradio import trellis
try:
import scipy.linalg
@@ -182,6 +182,7 @@ psk4=(2,[1, 0, \
0, 1, \
0, -1,\
-1, 0]) # includes Gray mapping
+
psk8=(2,[math.cos(2*math.pi*0/8), math.sin(2*math.pi*0/8), \
math.cos(2*math.pi*1/8), math.sin(2*math.pi*1/8), \
math.cos(2*math.pi*2/8), math.sin(2*math.pi*2/8), \
@@ -191,6 +192,32 @@ psk8=(2,[math.cos(2*math.pi*0/8), math.sin(2*math.pi*0/8), \
math.cos(2*math.pi*6/8), math.sin(2*math.pi*6/8), \
math.cos(2*math.pi*7/8), math.sin(2*math.pi*7/8)])
+psk2x3 = (3,[-1,-1,-1, \
+ -1,-1,1, \
+ -1,1,-1, \
+ -1,1,1, \
+ 1,-1,-1, \
+ 1,-1,1, \
+ 1,1,-1, \
+ 1,1,1])
+
+psk2x4 = (4,[-1,-1,-1,-1, \
+ -1,-1,-1,1, \
+ -1,-1,1,-1, \
+ -1,-1,1,1, \
+ -1,1,-1,-1, \
+ -1,1,-1,1, \
+ -1,1,1,-1, \
+ -1,1,1,1, \
+ 1,-1,-1,-1, \
+ 1,-1,-1,1, \
+ 1,-1,1,-1, \
+ 1,-1,1,1, \
+ 1,1,-1,-1, \
+ 1,1,-1,1, \
+ 1,1,1,-1, \
+ 1,1,1,1])
+
orth2 = (2,[1, 0, \
0, 1])
orth4=(4,[1, 0, 0, 0, \
@@ -205,35 +232,3 @@ orth4=(4,[1, 0, 0, 0, \
# C test channel (J. Proakis, Digital Communications, McGraw-Hill Inc., 2001)
c_channel = [0.227, 0.460, 0.688, 0.460, 0.227]
-
-
-
-
-
-
-
-
-
-if __name__ == '__main__':
- f1=trellis.fsm('fsm_files/awgn1o2_4.fsm')
- #f2=trellis.fsm('fsm_files/awgn2o3_4.fsm')
- #print f1.I(), f1.S(), f1.O()
- #print f1.NS()
- #print f1.OS()
- #print f2.I(), f2.S(), f2.O()
- #print f2.NS()
- #print f2.OS()
- ##f1.write_trellis_svg('f1.svg',4)
- #f2.write_trellis_svg('f2.svg',4)
- #f=fsm_concatenate(f1,f2)
- #f=fsm_radix(f1,2)
-
- #print "----------\n"
- #print f.I(), f.S(), f.O()
- #print f.NS()
- #print f.OS()
- #f.write_trellis_svg('f.svg',4)
-
- q=numpy.arange(0,8)/(2.0*8)
- (f0,SS,S,F,Sf,Ff,N) = make_cpm_signals(1,2,2,1,q,0.99)
-
diff --git a/gr-uhd/lib/usrp_sink_impl.cc b/gr-uhd/lib/usrp_sink_impl.cc
index 1a17e87775..c184f0a406 100644
--- a/gr-uhd/lib/usrp_sink_impl.cc
+++ b/gr-uhd/lib/usrp_sink_impl.cc
@@ -88,7 +88,7 @@ namespace gr {
{
bool clocks_locked = true;
- // 1) Check ref lock for all mboards
+ // Check ref lock for all mboards
for (size_t mboard_index = 0; mboard_index < _dev->get_num_mboards(); mboard_index++) {
std::string sensor_name = "ref_locked";
if (_dev->get_clock_source(mboard_index) == "internal") {
@@ -107,19 +107,6 @@ namespace gr {
}
}
- // 2) Check LO for all channels
- for (size_t i = 0; i < _nchan; i++) {
- size_t chan_index = _stream_args.channels[i];
- if (not _wait_for_locked_sensor(
- get_sensor_names(chan_index),
- "lo_locked",
- boost::bind(&usrp_sink_impl::get_sensor, this, _1, chan_index)
- )) {
- GR_LOG_WARN(d_logger, boost::format("Sensor 'lo_locked' failed to lock within timeout on channel %d.") % chan_index);
- clocks_locked = false;
- }
- }
-
return clocks_locked;
}
diff --git a/gr-uhd/lib/usrp_source_impl.cc b/gr-uhd/lib/usrp_source_impl.cc
index 6be0bac9ca..3142627952 100644
--- a/gr-uhd/lib/usrp_source_impl.cc
+++ b/gr-uhd/lib/usrp_source_impl.cc
@@ -87,7 +87,7 @@ namespace gr {
{
bool clocks_locked = true;
- // 1) Check ref lock for all mboards
+ // Check ref lock for all mboards
for (size_t mboard_index = 0; mboard_index < _dev->get_num_mboards(); mboard_index++) {
std::string sensor_name = "ref_locked";
if (_dev->get_clock_source(mboard_index) == "internal") {
@@ -106,19 +106,6 @@ namespace gr {
}
}
- // 2) Check LO for all channels
- for (size_t i = 0; i < _nchan; i++) {
- size_t chan_index = _stream_args.channels[i];
- if (not _wait_for_locked_sensor(
- get_sensor_names(chan_index),
- "lo_locked",
- boost::bind(&usrp_source_impl::get_sensor, this, _1, chan_index)
- )) {
- GR_LOG_WARN(d_logger, boost::format("Sensor 'lo_locked' failed to lock within timeout on channel %d.") % chan_index);
- clocks_locked = false;
- }
- }
-
return clocks_locked;
}
diff --git a/gr-utils/python/modtool/gr-newmod/cmake/Modules/FindCppUnit.cmake b/gr-utils/python/modtool/gr-newmod/cmake/Modules/FindCppUnit.cmake
index 9af308f84b..f93ade3412 100644
--- a/gr-utils/python/modtool/gr-newmod/cmake/Modules/FindCppUnit.cmake
+++ b/gr-utils/python/modtool/gr-newmod/cmake/Modules/FindCppUnit.cmake
@@ -15,6 +15,7 @@ PKG_CHECK_MODULES(PC_CPPUNIT "cppunit")
FIND_PATH(CPPUNIT_INCLUDE_DIRS
NAMES cppunit/TestCase.h
HINTS ${PC_CPPUNIT_INCLUDE_DIR}
+ ${CMAKE_INSTALL_PREFIX}/include
PATHS
/usr/local/include
/usr/include
@@ -23,6 +24,8 @@ FIND_PATH(CPPUNIT_INCLUDE_DIRS
FIND_LIBRARY(CPPUNIT_LIBRARIES
NAMES cppunit
HINTS ${PC_CPPUNIT_LIBDIR}
+ ${CMAKE_INSTALL_PREFIX}/lib
+ ${CMAKE_INSTALL_PREFIX}/lib64
PATHS
${CPPUNIT_INCLUDE_DIRS}/../lib
/usr/local/lib
diff --git a/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrMiscUtils.cmake b/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrMiscUtils.cmake
index 9331d5debc..188c40480b 100644
--- a/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrMiscUtils.cmake
+++ b/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrMiscUtils.cmake
@@ -1,4 +1,4 @@
-# Copyright 2010-2011 Free Software Foundation, Inc.
+# Copyright 2010-2011,2014 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -94,7 +94,13 @@ macro(GR_ADD_CXX_COMPILER_FLAG_IF_AVAILABLE flag have)
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG(${flag} ${have})
if(${have})
- add_definitions(${flag})
+ if(${CMAKE_VERSION} VERSION_GREATER "2.8.4")
+ STRING(FIND "${CMAKE_CXX_FLAGS}" "${flag}" flag_dup)
+ if(${flag_dup} EQUAL -1)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
+ endif(${flag_dup} EQUAL -1)
+ endif(${CMAKE_VERSION} VERSION_GREATER "2.8.4")
endif(${have})
endmacro(GR_ADD_CXX_COMPILER_FLAG_IF_AVAILABLE)
@@ -155,7 +161,7 @@ function(GR_LIBRARY_FOO target)
GR_LIBTOOL(TARGET ${target} DESTINATION ${GR_LIBRARY_DIR})
#give the library a special name with ultra-zero soversion
- set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_NAME ${target}-${LIBVER} SOVERSION "0.0.0")
+ set_target_properties(${target} PROPERTIES OUTPUT_NAME ${target}-${LIBVER} SOVERSION "0.0.0")
set(target_name lib${target}-${LIBVER}.so.0.0.0)
#custom command to generate symlinks
@@ -208,3 +214,312 @@ function(GR_GEN_TARGET_DEPS name var)
set(${var} "DEPENDS;${name};COMMAND;${name}" PARENT_SCOPE)
endif()
endfunction(GR_GEN_TARGET_DEPS)
+
+########################################################################
+# Control use of gr_logger
+# Usage:
+# GR_LOGGING()
+#
+# Will set ENABLE_GR_LOG to 1 by default.
+# Can manually set with -DENABLE_GR_LOG=0|1
+########################################################################
+function(GR_LOGGING)
+ find_package(Log4cpp)
+
+ OPTION(ENABLE_GR_LOG "Use gr_logger" ON)
+ if(ENABLE_GR_LOG)
+ # If gr_logger is enabled, make it usable
+ add_definitions( -DENABLE_GR_LOG )
+
+ # also test LOG4CPP; if we have it, use this version of the logger
+ # otherwise, default to the stdout/stderr model.
+ if(LOG4CPP_FOUND)
+ SET(HAVE_LOG4CPP True CACHE INTERNAL "" FORCE)
+ add_definitions( -DHAVE_LOG4CPP )
+ else(not LOG4CPP_FOUND)
+ SET(HAVE_LOG4CPP False CACHE INTERNAL "" FORCE)
+ SET(LOG4CPP_INCLUDE_DIRS "" CACHE INTERNAL "" FORCE)
+ SET(LOG4CPP_LIBRARY_DIRS "" CACHE INTERNAL "" FORCE)
+ SET(LOG4CPP_LIBRARIES "" CACHE INTERNAL "" FORCE)
+ endif(LOG4CPP_FOUND)
+
+ SET(ENABLE_GR_LOG ${ENABLE_GR_LOG} CACHE INTERNAL "" FORCE)
+
+ else(ENABLE_GR_LOG)
+ SET(HAVE_LOG4CPP False CACHE INTERNAL "" FORCE)
+ SET(LOG4CPP_INCLUDE_DIRS "" CACHE INTERNAL "" FORCE)
+ SET(LOG4CPP_LIBRARY_DIRS "" CACHE INTERNAL "" FORCE)
+ SET(LOG4CPP_LIBRARIES "" CACHE INTERNAL "" FORCE)
+ endif(ENABLE_GR_LOG)
+
+ message(STATUS "ENABLE_GR_LOG set to ${ENABLE_GR_LOG}.")
+ message(STATUS "HAVE_LOG4CPP set to ${HAVE_LOG4CPP}.")
+ message(STATUS "LOG4CPP_LIBRARIES set to ${LOG4CPP_LIBRARIES}.")
+
+endfunction(GR_LOGGING)
+
+########################################################################
+# Run GRCC to compile .grc files into .py files.
+#
+# Usage: GRCC(filename, directory)
+# - filenames: List of file name of .grc file
+# - directory: directory of built .py file - usually in
+# ${CMAKE_CURRENT_BINARY_DIR}
+# - Sets PYFILES: output converted GRC file names to Python files.
+########################################################################
+function(GRCC)
+ # Extract directory from list of args, remove it for the list of filenames.
+ list(GET ARGV -1 directory)
+ list(REMOVE_AT ARGV -1)
+ set(filenames ${ARGV})
+ file(MAKE_DIRECTORY ${directory})
+
+ SET(GRCC_COMMAND ${CMAKE_SOURCE_DIR}/gr-utils/python/grcc)
+
+ # GRCC uses some stuff in grc and gnuradio-runtime, so we force
+ # the known paths here
+ list(APPEND PYTHONPATHS
+ ${CMAKE_SOURCE_DIR}
+ ${CMAKE_SOURCE_DIR}/gnuradio-runtime/python
+ ${CMAKE_SOURCE_DIR}/gnuradio-runtime/lib/swig
+ ${CMAKE_BINARY_DIR}/gnuradio-runtime/lib/swig
+ )
+
+ if(WIN32)
+ #SWIG generates the python library files into a subdirectory.
+ #Therefore, we must append this subdirectory into PYTHONPATH.
+ #Only do this for the python directories matching the following:
+ foreach(pydir ${PYTHONPATHS})
+ get_filename_component(name ${pydir} NAME)
+ if(name MATCHES "^(swig|lib|src)$")
+ list(APPEND PYTHONPATHS ${pydir}/${CMAKE_BUILD_TYPE})
+ endif()
+ endforeach(pydir)
+ endif(WIN32)
+
+ file(TO_NATIVE_PATH "${PYTHONPATHS}" pypath)
+
+ if(UNIX)
+ list(APPEND pypath "$PYTHONPATH")
+ string(REPLACE ";" ":" pypath "${pypath}")
+ set(ENV{PYTHONPATH} ${pypath})
+ endif(UNIX)
+
+ if(WIN32)
+ list(APPEND pypath "%PYTHONPATH%")
+ string(REPLACE ";" "\\;" pypath "${pypath}")
+ #list(APPEND environs "PYTHONPATH=${pypath}")
+ set(ENV{PYTHONPATH} ${pypath})
+ endif(WIN32)
+
+ foreach(f ${filenames})
+ execute_process(
+ COMMAND ${GRCC_COMMAND} -d ${directory} ${f}
+ )
+ string(REPLACE ".grc" ".py" pyfile "${f}")
+ string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" pyfile "${pyfile}")
+ list(APPEND pyfiles ${pyfile})
+ endforeach(f)
+
+ set(PYFILES ${pyfiles} PARENT_SCOPE)
+endfunction(GRCC)
+
+########################################################################
+# Check if HAVE_PTHREAD_SETSCHEDPARAM and HAVE_SCHED_SETSCHEDULER
+# should be defined
+########################################################################
+macro(GR_CHECK_LINUX_SCHED_AVAIL)
+set(CMAKE_REQUIRED_LIBRARIES -lpthread)
+ CHECK_CXX_SOURCE_COMPILES("
+ #include <pthread.h>
+ int main(){
+ pthread_t pthread;
+ pthread_setschedparam(pthread, 0, 0);
+ return 0;
+ } " HAVE_PTHREAD_SETSCHEDPARAM
+ )
+ GR_ADD_COND_DEF(HAVE_PTHREAD_SETSCHEDPARAM)
+
+ CHECK_CXX_SOURCE_COMPILES("
+ #include <sched.h>
+ int main(){
+ pid_t pid;
+ sched_setscheduler(pid, 0, 0);
+ return 0;
+ } " HAVE_SCHED_SETSCHEDULER
+ )
+ GR_ADD_COND_DEF(HAVE_SCHED_SETSCHEDULER)
+endmacro(GR_CHECK_LINUX_SCHED_AVAIL)
+
+########################################################################
+# Macros to generate source and header files from template
+########################################################################
+macro(GR_EXPAND_X_H component root)
+
+ include(GrPython)
+
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
+"#!${PYTHON_EXECUTABLE}
+
+import sys, os, re
+sys.path.append('${GR_RUNTIME_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, '${component}')
+ build_utils.expand_template(d, inp)
+")
+
+ #make a list of all the generated headers
+ 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)
+ unset(name)
+
+ #create a command to generate the headers
+ 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 headers
+ list(APPEND generated_includes ${expanded_files_h})
+
+endmacro(GR_EXPAND_X_H)
+
+macro(GR_EXPAND_X_CC_H component root)
+
+ include(GrPython)
+
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
+"#!${PYTHON_EXECUTABLE}
+
+import sys, os, re
+sys.path.append('${GR_RUNTIME_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, '${component}')
+ build_utils.expand_template(d, inp)
+")
+
+ #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)
+ unset(name)
+
+ #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 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}
+ )
+
+ #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 files
+ list(APPEND generated_sources ${expanded_files_cc})
+ list(APPEND generated_headers ${expanded_files_h})
+
+endmacro(GR_EXPAND_X_CC_H)
+
+macro(GR_EXPAND_X_CC_H_IMPL component root)
+
+ include(GrPython)
+
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
+"#!${PYTHON_EXECUTABLE}
+
+import sys, os, re
+sys.path.append('${GR_RUNTIME_PYTHONPATH}')
+os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
+os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
+
+if __name__ == '__main__':
+ import build_utils
+ root, inp = sys.argv[1:3]
+ for sig in sys.argv[3:]:
+ name = re.sub ('X+', sig, root)
+ d = build_utils.standard_dict(name, sig, '${component}')
+ build_utils.expand_template(d, inp, '_impl')
+")
+
+ #make a list of all the generated files
+ unset(expanded_files_cc_impl)
+ unset(expanded_files_h_impl)
+ unset(expanded_files_h)
+ foreach(sig ${ARGN})
+ string(REGEX REPLACE "X+" ${sig} name ${root})
+ list(APPEND expanded_files_cc_impl ${CMAKE_CURRENT_BINARY_DIR}/${name}_impl.cc)
+ list(APPEND expanded_files_h_impl ${CMAKE_CURRENT_BINARY_DIR}/${name}_impl.h)
+ list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/../include/gnuradio/${component}/${name}.h)
+ endforeach(sig)
+ unset(name)
+
+ #create a command to generate the _impl.cc files
+ add_custom_command(
+ OUTPUT ${expanded_files_cc_impl}
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}_impl.cc.t
+ COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
+ ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
+ ${root} ${root}_impl.cc.t ${ARGN}
+ )
+
+ #create a command to generate the _impl.h files
+ add_custom_command(
+ OUTPUT ${expanded_files_h_impl}
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}_impl.h.t
+ COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
+ ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
+ ${root} ${root}_impl.h.t ${ARGN}
+ )
+
+ #make _impl.cc source files depend on _impl.h to force generation
+ set_source_files_properties(${expanded_files_cc_impl}
+ PROPERTIES OBJECT_DEPENDS "${expanded_files_h_impl}"
+ )
+
+ #make _impl.h source files depend on headers to force generation
+ set_source_files_properties(${expanded_files_h_impl}
+ PROPERTIES OBJECT_DEPENDS "${expanded_files_h}"
+ )
+
+ #install rules for the generated files
+ list(APPEND generated_sources ${expanded_files_cc_impl})
+ list(APPEND generated_headers ${expanded_files_h_impl})
+
+endmacro(GR_EXPAND_X_CC_H_IMPL)
diff --git a/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrPlatform.cmake b/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrPlatform.cmake
index a2e4f3b34e..5b7e886f85 100644
--- a/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrPlatform.cmake
+++ b/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrPlatform.cmake
@@ -37,10 +37,18 @@ if(LINUX AND EXISTS "/etc/redhat-release")
set(REDHAT TRUE)
endif()
+if(LINUX AND EXISTS "/etc/slackware-version")
+ set(SLACKWARE TRUE)
+endif()
+
########################################################################
# when the library suffix should be 64 (applies to redhat linux family)
########################################################################
-if(NOT DEFINED LIB_SUFFIX AND REDHAT AND CMAKE_SYSTEM_PROCESSOR MATCHES "64$")
+if (REDHAT OR SLACKWARE)
+ set(LIB64_CONVENTION TRUE)
+endif()
+
+if(NOT DEFINED LIB_SUFFIX AND LIB64_CONVENTION AND CMAKE_SYSTEM_PROCESSOR MATCHES "64$")
set(LIB_SUFFIX 64)
endif()
set(LIB_SUFFIX ${LIB_SUFFIX} CACHE STRING "lib directory suffix")
diff --git a/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrPython.cmake b/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrPython.cmake
index 68ca58e996..395faffa5a 100644
--- a/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrPython.cmake
+++ b/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrPython.cmake
@@ -48,8 +48,15 @@ else(PYTHON_EXECUTABLE)
endif(PYTHON_EXECUTABLE)
+if (CMAKE_CROSSCOMPILING)
+ set(QA_PYTHON_EXECUTABLE "/usr/bin/python")
+else (CMAKE_CROSSCOMPILING)
+ set(QA_PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE})
+endif(CMAKE_CROSSCOMPILING)
+
#make the path to the executable appear in the cmake gui
set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter")
+set(QA_PYTHON_EXECUTABLE ${QA_PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter for QA tests")
#make sure we can use -B with python (introduced in 2.6)
if(PYTHON_EXECUTABLE)
@@ -76,10 +83,11 @@ macro(GR_PYTHON_CHECK_MODULE desc mod cmd have)
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -c "
#########################################
-try: import ${mod}
-except: exit(-1)
-try: assert ${cmd}
-except: exit(-1)
+try:
+ import ${mod}
+ assert ${cmd}
+except ImportError, AssertionError: exit(-1)
+except: pass
#########################################"
RESULT_VARIABLE ${have}
)
@@ -95,11 +103,13 @@ endmacro(GR_PYTHON_CHECK_MODULE)
########################################################################
# Sets the python installation directory GR_PYTHON_DIR
########################################################################
+if(NOT DEFINED GR_PYTHON_DIR)
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "
from distutils import sysconfig
print sysconfig.get_python_lib(plat_specific=True, prefix='')
" OUTPUT_VARIABLE GR_PYTHON_DIR OUTPUT_STRIP_TRAILING_WHITESPACE
)
+endif()
file(TO_CMAKE_PATH ${GR_PYTHON_DIR} GR_PYTHON_DIR)
########################################################################
@@ -181,6 +191,10 @@ function(GR_PYTHON_INSTALL)
####################################################################
file(TO_NATIVE_PATH ${PYTHON_EXECUTABLE} pyexe_native)
+ if (CMAKE_CROSSCOMPILING)
+ set(pyexe_native "/usr/bin/env python")
+ endif()
+
foreach(pyfile ${GR_PYTHON_INSTALL_PROGRAMS})
get_filename_component(pyfile_name ${pyfile} NAME)
get_filename_component(pyfile ${pyfile} ABSOLUTE)
@@ -193,8 +207,9 @@ function(GR_PYTHON_INSTALL)
add_custom_command(
OUTPUT ${pyexefile} DEPENDS ${pyfile}
COMMAND ${PYTHON_EXECUTABLE} -c
- \"open('${pyexefile}', 'w').write('\#!${pyexe_native}\\n'+open('${pyfile}').read())\"
+ "open('${pyexefile}','w').write('\#!${pyexe_native}\\n'+open('${pyfile}').read())"
COMMENT "Shebangin ${pyfile_name}"
+ VERBATIM
)
#on windows, python files need an extension to execute
diff --git a/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrSwig.cmake b/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrSwig.cmake
index 569667b0e9..abf4dc4612 100644
--- a/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrSwig.cmake
+++ b/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrSwig.cmake
@@ -33,14 +33,13 @@ include(GrPython)
# - GR_SWIG_DOCS_TARGET_DEPS
########################################################################
function(GR_SWIG_MAKE_DOCS output_file)
- find_package(Doxygen)
- if(DOXYGEN_FOUND)
+ if(ENABLE_DOXYGEN)
#setup the input files variable list, quote formated
set(input_files)
unset(INPUT_PATHS)
foreach(input_path ${ARGN})
- if (IS_DIRECTORY ${input_path}) #when input path is a directory
+ if(IS_DIRECTORY ${input_path}) #when input path is a directory
file(GLOB input_path_h_files ${input_path}/*.h)
else() #otherwise its just a file, no glob
set(input_path_h_files ${input_path})
@@ -76,17 +75,18 @@ function(GR_SWIG_MAKE_DOCS output_file)
#call the swig_doc script on the xml files
add_custom_command(
OUTPUT ${output_file}
- DEPENDS ${input_files} ${OUTPUT_DIRECTORY}/xml/index.xml
+ DEPENDS ${input_files} ${stamp-file} ${OUTPUT_DIRECTORY}/xml/index.xml
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
${CMAKE_SOURCE_DIR}/docs/doxygen/swig_doc.py
${OUTPUT_DIRECTORY}/xml
${output_file}
+ COMMENT "Generating python docstrings for ${name}"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs/doxygen
)
- else(DOXYGEN_FOUND)
+ else(ENABLE_DOXYGEN)
file(WRITE ${output_file} "\n") #no doxygen -> empty file
- endif(DOXYGEN_FOUND)
+ endif(ENABLE_DOXYGEN)
endfunction(GR_SWIG_MAKE_DOCS)
########################################################################
@@ -105,20 +105,35 @@ endfunction(GR_SWIG_MAKE_DOCS)
macro(GR_SWIG_MAKE name)
set(ifiles ${ARGN})
+ # Shimming this in here to take care of a SWIG bug with handling
+ # vector<size_t> and vector<unsigned int> (on 32-bit machines) and
+ # vector<long unsigned int> (on 64-bit machines). Use this to test
+ # the size of size_t, then set SIZE_T_32 if it's a 32-bit machine
+ # or not if it's 64-bit. The logic in gr_type.i handles the rest.
+ INCLUDE(CheckTypeSize)
+ CHECK_TYPE_SIZE("size_t" SIZEOF_SIZE_T)
+ CHECK_TYPE_SIZE("unsigned int" SIZEOF_UINT)
+ if(${SIZEOF_SIZE_T} EQUAL ${SIZEOF_UINT})
+ list(APPEND GR_SWIG_FLAGS -DSIZE_T_32)
+ endif(${SIZEOF_SIZE_T} EQUAL ${SIZEOF_UINT})
+
#do swig doc generation if specified
- if (GR_SWIG_DOC_FILE)
+ if(GR_SWIG_DOC_FILE)
set(GR_SWIG_DOCS_SOURCE_DEPS ${GR_SWIG_SOURCE_DEPS})
- set(GR_SWIG_DOCS_TAREGT_DEPS ${GR_SWIG_TARGET_DEPS})
+ list(APPEND GR_SWIG_DOCS_TARGET_DEPS ${GR_SWIG_TARGET_DEPS})
GR_SWIG_MAKE_DOCS(${GR_SWIG_DOC_FILE} ${GR_SWIG_DOC_DIRS})
- list(APPEND GR_SWIG_SOURCE_DEPS ${GR_SWIG_DOC_FILE})
+ add_custom_target(${name}_swig_doc DEPENDS ${GR_SWIG_DOC_FILE})
+ list(APPEND GR_SWIG_TARGET_DEPS ${name}_swig_doc ${GR_RUNTIME_SWIG_DOC_FILE})
endif()
#append additional include directories
find_package(PythonLibs 2)
list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_PATH}) #deprecated name (now dirs)
list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS})
- list(APPEND GR_SWIG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR})
- list(APPEND GR_SWIG_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR})
+
+ #prepend local swig directories
+ list(INSERT GR_SWIG_INCLUDE_DIRS 0 ${CMAKE_CURRENT_SOURCE_DIR})
+ list(INSERT GR_SWIG_INCLUDE_DIRS 0 ${CMAKE_CURRENT_BINARY_DIR})
#determine include dependencies for swig file
execute_process(
@@ -157,6 +172,9 @@ macro(GR_SWIG_MAKE name)
include(UseSWIG)
SWIG_ADD_MODULE(${name} python ${ifiles})
SWIG_LINK_LIBRARIES(${name} ${PYTHON_LIBRARIES} ${GR_SWIG_LIBRARIES})
+ if(${name} STREQUAL "runtime_swig")
+ SET_TARGET_PROPERTIES(${SWIG_MODULE_runtime_swig_REAL_NAME} PROPERTIES DEFINE_SYMBOL "gnuradio_runtime_EXPORTS")
+ endif(${name} STREQUAL "runtime_swig")
endmacro(GR_SWIG_MAKE)
@@ -204,21 +222,25 @@ file(WRITE ${CMAKE_BINARY_DIR}/get_swig_deps.py "
import os, sys, re
-include_matcher = re.compile('[#|%]include\\s*[<|\"](.*)[>|\"]')
+i_include_matcher = re.compile('%(include|import)\\s*[<|\"](.*)[>|\"]')
+h_include_matcher = re.compile('#(include)\\s*[<|\"](.*)[>|\"]')
include_dirs = sys.argv[2].split(';')
def get_swig_incs(file_path):
+ if file_path.endswith('.i'): matcher = i_include_matcher
+ else: matcher = h_include_matcher
file_contents = open(file_path, 'r').read()
- return include_matcher.findall(file_contents, re.MULTILINE)
+ return matcher.findall(file_contents, re.MULTILINE)
def get_swig_deps(file_path, level):
deps = [file_path]
if level == 0: return deps
- for inc_file in get_swig_incs(file_path):
+ for keyword, inc_file in get_swig_incs(file_path):
for inc_dir in include_dirs:
inc_path = os.path.join(inc_dir, inc_file)
if not os.path.exists(inc_path): continue
deps.extend(get_swig_deps(inc_path, level-1))
+ break #found, we dont search in lower prio inc dirs
return deps
if __name__ == '__main__':
diff --git a/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrTest.cmake b/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrTest.cmake
index 6174c034e9..62caab4b51 100644
--- a/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrTest.cmake
+++ b/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrTest.cmake
@@ -30,10 +30,10 @@ set(__INCLUDED_GR_TEST_CMAKE TRUE)
# GR_TEST_TARGET_DEPS - built targets for the library path
# GR_TEST_LIBRARY_DIRS - directories for the library path
# GR_TEST_PYTHON_DIRS - directories for the python path
+# GR_TEST_ENVIRONS - other environment key/value pairs
########################################################################
function(GR_ADD_TEST test_name)
- if(WIN32)
#Ensure that the build exe also appears in the PATH.
list(APPEND GR_TEST_TARGET_DEPS ${ARGN})
@@ -50,6 +50,7 @@ function(GR_ADD_TEST test_name)
endif(location)
endforeach(target)
+ if(WIN32)
#SWIG generates the python library files into a subdirectory.
#Therefore, we must append this subdirectory into PYTHONPATH.
#Only do this for the python directories matching the following:
@@ -65,7 +66,8 @@ function(GR_ADD_TEST test_name)
file(TO_NATIVE_PATH "${GR_TEST_LIBRARY_DIRS}" libpath) #ok to use on dir list?
file(TO_NATIVE_PATH "${GR_TEST_PYTHON_DIRS}" pypath) #ok to use on dir list?
- set(environs "GR_DONT_LOAD_PREFS=1" "srcdir=${srcdir}")
+ set(environs "VOLK_GENERIC=1" "GR_DONT_LOAD_PREFS=1" "srcdir=${srcdir}")
+ list(APPEND environs ${GR_TEST_ENVIRONS})
#http://www.cmake.org/pipermail/cmake/2009-May/029464.html
#Replaced this add test + set environs code with the shell script generation.
@@ -74,18 +76,26 @@ function(GR_ADD_TEST test_name)
#SET_TESTS_PROPERTIES(${test_name} PROPERTIES ENVIRONMENT "${environs}")
if(UNIX)
+ set(LD_PATH_VAR "LD_LIBRARY_PATH")
+ if(APPLE)
+ set(LD_PATH_VAR "DYLD_LIBRARY_PATH")
+ endif()
+
set(binpath "${CMAKE_CURRENT_BINARY_DIR}:$PATH")
- #set both LD and DYLD paths to cover multiple UNIX OS library paths
- list(APPEND libpath "$LD_LIBRARY_PATH" "$DYLD_LIBRARY_PATH")
+ list(APPEND libpath "$${LD_PATH_VAR}")
list(APPEND pypath "$PYTHONPATH")
#replace list separator with the path separator
string(REPLACE ";" ":" libpath "${libpath}")
string(REPLACE ";" ":" pypath "${pypath}")
- list(APPEND environs "PATH=${binpath}" "LD_LIBRARY_PATH=${libpath}" "DYLD_LIBRARY_PATH=${libpath}" "PYTHONPATH=${pypath}")
+ list(APPEND environs "PATH=${binpath}" "${LD_PATH_VAR}=${libpath}" "PYTHONPATH=${pypath}")
#generate a bat file that sets the environment and runs the test
- find_program(SHELL sh)
+ if (CMAKE_CROSSCOMPILING)
+ set(SHELL "/bin/sh")
+ else(CMAKE_CROSSCOMPILING)
+ find_program(SHELL sh)
+ endif(CMAKE_CROSSCOMPILING)
set(sh_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.sh)
file(WRITE ${sh_file} "#!${SHELL}\n")
#each line sets an environment variable
diff --git a/gr-utils/python/utils/grcc b/gr-utils/python/utils/grcc
index 8fb44c2c79..82db5435db 100755
--- a/gr-utils/python/utils/grcc
+++ b/gr-utils/python/utils/grcc
@@ -20,6 +20,9 @@
# Boston, MA 02110-1301, USA.
#
+import os
+import sys
+from optparse import OptionParser
import warnings
warnings.simplefilter('ignore')
@@ -28,10 +31,8 @@ try:
except ImportError:
from gnuradio.grc.python.Platform import Platform
-from optparse import OptionParser
-import os, sys
-class grcc:
+class GRCC:
def __init__(self, grcfile, out_dir):
self.out_dir = out_dir
self.platform = Platform()
@@ -43,7 +44,9 @@ class grcc:
self.fg.validate()
if not self.fg.is_valid():
- raise StandardError("Compilation error")
+ raise StandardError("\n\n".join(
+ ["Validation failed:"] + self.fg.get_error_messages()
+ ))
self.gen = self.platform.get_generator()(self.fg, out_dir)
self.gen.write()
@@ -52,7 +55,8 @@ class grcc:
progname = self.fg.get_option('id')
os.system("{0}/{1}.py".format(self.out_dir, progname))
-if __name__ == "__main__":
+
+def main():
usage="%prog: [options] filename"
description = "Compiles a GRC file (.grc) into a GNU Radio Python program. The program is stored in ~/.grc_gnuradio by default, but this location can be changed with the -d option."
@@ -63,15 +67,20 @@ if __name__ == "__main__":
help="Run the program after compiling [default=%default]")
(options, args) = parser.parse_args ()
- if(len(args) != 1):
+ if len(args) != 1:
sys.stderr.write("Please specify a GRC file name to compile.\n")
sys.exit(1)
try:
- g = grcc(args[0], options.directory+"/")
- except:
- sys.stderr.write("Error during file compilation.\n");
+ g = GRCC(args[0], options.directory + "/")
+ except Exception as e:
+ sys.stderr.write(str(e) + "\n")
+ sys.stderr.write("Error during file compilation.\n")
sys.exit(1)
- if(options.execute):
+ if options.execute:
g.exec_program()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/gr-wxgui/python/wxgui/fft_window.py b/gr-wxgui/python/wxgui/fft_window.py
index 86023e3f88..024200556e 100644
--- a/gr-wxgui/python/wxgui/fft_window.py
+++ b/gr-wxgui/python/wxgui/fft_window.py
@@ -336,8 +336,8 @@ class fft_window(wx.Panel, pubsub.pubsub):
samples = numpy.fromstring(msg, numpy.float32)[:self.fft_size] #only take first frame
num_samps = len(samples)
#reorder fft
- if self.real: samples = samples[:(num_samps+1)/2]
- else: samples = numpy.concatenate((samples[num_samps/2+1:], samples[:(num_samps+1)/2]))
+ if self.real: samples = samples[:(num_samps+2)/2]
+ else: samples = numpy.concatenate((samples[(num_samps+1)/2:], samples[:(num_samps+2)/2]))
self.samples = samples
#peak hold calculation
if self[PEAK_HOLD_KEY]:
@@ -407,6 +407,6 @@ class fft_window(wx.Panel, pubsub.pubsub):
#update y grid
self.plotter.set_y_grid(ref_level-y_per_div*y_divs, ref_level, y_per_div)
#update y units
- self.plotter.set_y_label('Amplitude', 'dB')
+ self.plotter.set_y_label('Power', 'dB')
#update plotter
self.plotter.update()
diff --git a/gr-wxgui/python/wxgui/fftsink_nongl.py b/gr-wxgui/python/wxgui/fftsink_nongl.py
index be69e41578..c63f0fb268 100644
--- a/gr-wxgui/python/wxgui/fftsink_nongl.py
+++ b/gr-wxgui/python/wxgui/fftsink_nongl.py
@@ -136,17 +136,17 @@ class fft_sink_f(gr.hier_block2, fft_sink_base):
for tap in mywindow:
power += tap*tap
- self.c2mag = blocks.complex_to_mag(self.fft_size)
+ self.c2magsq = blocks.complex_to_mag_squared(self.fft_size)
self.avg = grfilter.single_pole_iir_filter_ff(1.0, self.fft_size)
# FIXME We need to add 3dB to all bins but the DC bin
- self.log = blocks.nlog10_ff(20, self.fft_size,
+ self.log = blocks.nlog10_ff(10, self.fft_size,
-20*math.log10(self.fft_size) # Adjust for number of bins
-10*math.log10(power/self.fft_size) # Adjust for windowing loss
-20*math.log10(ref_scale/2)) # Adjust for reference scale
self.sink = blocks.message_sink(gr.sizeof_float * self.fft_size, self.msgq, True)
- self.connect(self, self.s2p, self.one_in_n, self.fft, self.c2mag, self.avg, self.log, self.sink)
+ self.connect(self, self.s2p, self.one_in_n, self.fft, self.c2magsq, self.avg, self.log, self.sink)
self.win = fft_window(self, parent, size=size)
self.set_average(self.average)
@@ -183,17 +183,17 @@ class fft_sink_c(gr.hier_block2, fft_sink_base):
for tap in mywindow:
power += tap*tap
- self.c2mag = blocks.complex_to_mag(self.fft_size)
+ self.c2magsq = blocks.complex_to_mag_squared(self.fft_size)
self.avg = grfilter.single_pole_iir_filter_ff(1.0, self.fft_size)
# FIXME We need to add 3dB to all bins but the DC bin
- self.log = blocks.nlog10_ff(20, self.fft_size,
+ self.log = blocks.nlog10_ff(10, self.fft_size,
-20*math.log10(self.fft_size) # Adjust for number of bins
-10*math.log10(power/self.fft_size) # Adjust for windowing loss
-20*math.log10(ref_scale/2)) # Adjust for reference scale
self.sink = blocks.message_sink(gr.sizeof_float * self.fft_size, self.msgq, True)
- self.connect(self, self.s2p, self.one_in_n, self.fft, self.c2mag, self.avg, self.log, self.sink)
+ self.connect(self, self.s2p, self.one_in_n, self.fft, self.c2magsq, self.avg, self.log, self.sink)
self.win = fft_window(self, parent, size=size)
self.set_average(self.average)
diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt
index cbf4c9945d..3714401bbb 100644
--- a/grc/CMakeLists.txt
+++ b/grc/CMakeLists.txt
@@ -67,6 +67,10 @@ CPACK_COMPONENT("grc"
# Create and install the grc conf file
########################################################################
file(TO_NATIVE_PATH ${CMAKE_INSTALL_PREFIX}/${GRC_BLOCKS_DIR} blocksdir)
+if(CMAKE_INSTALL_PREFIX STREQUAL "/usr")
+ # linux binary installs: append blocks dir with prefix /usr/local
+ set(blocksdir ${blocksdir}:/usr/local/${GRC_BLOCKS_DIR})
+endif(CMAKE_INSTALL_PREFIX STREQUAL "/usr")
if (APPLE)
set(GRC_XTERM_EXE "xterm")
diff --git a/grc/base/FlowGraph.py b/grc/base/FlowGraph.py
index 02d1b112c4..fb25b46821 100644
--- a/grc/base/FlowGraph.py
+++ b/grc/base/FlowGraph.py
@@ -17,11 +17,13 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
"""
+import time
from . import odict
from Element import Element
from .. gui import Messages
from . Constants import FLOW_GRAPH_FILE_FORMAT_VERSION
+
class FlowGraph(Element):
def __init__(self, platform):
@@ -36,6 +38,8 @@ class FlowGraph(Element):
"""
#initialize
Element.__init__(self, platform)
+ self._elements = []
+ self._timestamp = time.ctime()
#inital blank import
self.import_data()
@@ -51,12 +55,14 @@ class FlowGraph(Element):
"""
index = 0
while True:
- id = '%s_%d'%(base_id, index)
- index = index + 1
+ id = '%s_%d' % (base_id, index)
+ index += 1
#make sure that the id is not used by another block
if not filter(lambda b: b.get_id() == id, self.get_blocks()): return id
- def __str__(self): return 'FlowGraph - %s(%s)'%(self.get_option('title'), self.get_option('id'))
+ def __str__(self):
+ return 'FlowGraph - %s(%s)' % (self.get_option('title'), self.get_option('id'))
+
def rewrite(self):
def refactor_bus_structure():
@@ -242,9 +248,8 @@ class FlowGraph(Element):
Returns:
a nested data odict
"""
- import time
n = odict()
- n['timestamp'] = time.ctime()
+ n['timestamp'] = self._timestamp
n['block'] = [block.export_data() for block in self.get_blocks()]
n['connection'] = [connection.export_data() for connection in self.get_connections()]
instructions = odict({
@@ -273,6 +278,7 @@ class FlowGraph(Element):
file_format = 0
#use blank data if none provided
fg_n = n and n.find('flow_graph') or odict()
+ self._timestamp = fg_n.find('timestamp') or time.ctime()
blocks_n = fg_n.findall('block')
connections_n = fg_n.findall('connection')
#create option block
@@ -384,7 +390,7 @@ def _initialize_dummy_block(block, block_n):
"""
block._key = block_n.find('key')
block.is_dummy_block = lambda: True
- block.is_valid = lambda: False
+ block.is_valid = lambda: False
block.get_enabled = lambda: False
for param_n in block_n.findall('param'):
if param_n['key'] not in block.get_param_keys():
@@ -393,7 +399,7 @@ def _initialize_dummy_block(block, block_n):
def _dummy_block_add_port(block, key, dir):
- """This is so ugly... Add a port to a dummy-fied block"""
+ """This is so ugly... Add a port to a dummy-field block"""
port_n = odict({'name': '?', 'key': key, 'type': ''})
port = block.get_parent().get_parent().Port(block=block, n=port_n, dir=dir)
if port.is_source():
diff --git a/grc/blocks/options.xml b/grc/blocks/options.xml
index 0c3a804fd7..c1c94e4e24 100644
--- a/grc/blocks/options.xml
+++ b/grc/blocks/options.xml
@@ -58,17 +58,17 @@ else: self.stop(); self.wait()</callback>
<param>
<name>Generate Options</name>
<key>generate_options</key>
- <value>wx_gui</value>
+ <value>qt_gui</value>
<type>enum</type>
<option>
- <name>WX GUI</name>
- <key>wx_gui</key>
- </option>
- <option>
<name>QT GUI</name>
<key>qt_gui</key>
</option>
<option>
+ <name>WX GUI</name>
+ <key>wx_gui</key>
+ </option>
+ <option>
<name>No GUI</name>
<key>no_gui</key>
</option>
diff --git a/grc/blocks/pad_sink.xml b/grc/blocks/pad_sink.xml
index 37e132c34c..b022fa3d0d 100644
--- a/grc/blocks/pad_sink.xml
+++ b/grc/blocks/pad_sink.xml
@@ -7,9 +7,7 @@
<block>
<name>Pad Sink</name>
<key>pad_sink</key>
- <make>#if str($type) == "message"
-None;self.message_port_register_hier_in($label)
-#end if</make>
+ <make></make>
<param>
<name>Label</name>
<key>label</key>
diff --git a/grc/blocks/pad_source.xml b/grc/blocks/pad_source.xml
index 745e48c080..c0fb19eee7 100644
--- a/grc/blocks/pad_source.xml
+++ b/grc/blocks/pad_source.xml
@@ -7,9 +7,7 @@
<block>
<name>Pad Source</name>
<key>pad_source</key>
- <make>#if str($type) == "message"
-None;self.message_port_register_hier_out($label)
-#end if</make>
+ <make></make>
<param>
<name>Label</name>
<key>label</key>
diff --git a/grc/gui/ActionHandler.py b/grc/gui/ActionHandler.py
index f8963fa472..6c56a94e9c 100644
--- a/grc/gui/ActionHandler.py
+++ b/grc/gui/ActionHandler.py
@@ -495,9 +495,11 @@ class ActionHandler:
ExecFlowGraphThread(self)
elif action == Actions.FLOW_GRAPH_KILL:
if self.get_page().get_proc():
- try: self.get_page().get_proc().kill()
- except: print "could not kill process: %d"%self.get_page().get_proc().pid
- elif action == Actions.PAGE_CHANGE: #pass and run the global actions
+ try:
+ self.get_page().get_proc().kill()
+ except:
+ print "could not kill process: %d" % self.get_page().get_proc().pid
+ elif action == Actions.PAGE_CHANGE: # pass and run the global actions
pass
elif action == Actions.RELOAD_BLOCKS:
self.platform.load_blocks()
@@ -583,7 +585,7 @@ class ActionHandler:
sensitive = self.get_flow_graph().is_valid() and not self.get_page().get_proc()
Actions.FLOW_GRAPH_GEN.set_sensitive(sensitive)
Actions.FLOW_GRAPH_EXEC.set_sensitive(sensitive)
- Actions.FLOW_GRAPH_KILL.set_sensitive(self.get_page().get_proc() != None)
+ Actions.FLOW_GRAPH_KILL.set_sensitive(self.get_page().get_proc() is not None)
class ExecFlowGraphThread(Thread):
"""Execute the flow graph as a new process and wait on it to finish."""
@@ -619,13 +621,14 @@ class ExecFlowGraphThread(Thread):
"""
#handle completion
r = "\n"
- while(r):
+ while r:
gobject.idle_add(Messages.send_verbose_exec, r)
r = os.read(self.p.stdout.fileno(), 1024)
+ self.p.poll()
gobject.idle_add(self.done)
def done(self):
"""Perform end of execution tasks."""
- Messages.send_end_exec()
+ Messages.send_end_exec(self.p.returncode)
self.page.set_proc(None)
self.update_exec_stop()
diff --git a/grc/gui/Block.py b/grc/gui/Block.py
index 1a32f6c2ba..9b8d3b1b56 100644
--- a/grc/gui/Block.py
+++ b/grc/gui/Block.py
@@ -25,7 +25,7 @@ from Constants import BORDER_PROXIMITY_SENSITIVITY
from Constants import \
BLOCK_LABEL_PADDING, \
PORT_SEPARATION, LABEL_SEPARATION, \
- PORT_BORDER_SEPARATION, POSSIBLE_ROTATIONS
+ PORT_BORDER_SEPARATION, POSSIBLE_ROTATIONS, BLOCK_FONT, PARAM_FONT
import Actions
import pygtk
pygtk.require('2.0')
@@ -34,7 +34,7 @@ import pango
BLOCK_MARKUP_TMPL="""\
#set $foreground = $block.is_valid() and 'black' or 'red'
-<span foreground="$foreground" font_desc="Sans 8"><b>$encode($block.get_name())</b></span>"""
+<span foreground="$foreground" font_desc="$font"><b>$encode($block.get_name())</b></span>"""
class Block(Element):
"""The graphical signal block."""
@@ -146,11 +146,13 @@ class Block(Element):
#create the main layout
layout = gtk.DrawingArea().create_pango_layout('')
layouts.append(layout)
- layout.set_markup(Utils.parse_template(BLOCK_MARKUP_TMPL, block=self))
+ layout.set_markup(Utils.parse_template(BLOCK_MARKUP_TMPL, block=self, font=BLOCK_FONT))
self.label_width, self.label_height = layout.get_pixel_size()
#display the params
if self.is_dummy_block():
- markups = ['<span foreground="black" font_desc="Sans 7.5"><b>key: </b>{}</span>'.format(self._key)]
+ markups = [
+ '<span foreground="black" font_desc="$font"><b>key: </b>{key}</span>'.format(font=PARAM_FONT, key=self._key)
+ ]
else:
markups = [param.get_markup() for param in self.get_params() if param.get_hide() not in ('all', 'part')]
if markups:
diff --git a/grc/gui/Constants.py b/grc/gui/Constants.py
index 7db291df99..0dc6279fd2 100644
--- a/grc/gui/Constants.py
+++ b/grc/gui/Constants.py
@@ -41,6 +41,13 @@ MIN_DIALOG_HEIGHT = 500
##default sizes
DEFAULT_BLOCKS_WINDOW_WIDTH = 100
DEFAULT_REPORTS_WINDOW_WIDTH = 100
+## flow-graph canvas fonts
+FONT_FAMILY = "Sans"
+FONT_SIZE = 8
+BLOCK_FONT = "%s %f" % (FONT_FAMILY, FONT_SIZE)
+PORT_FONT = BLOCK_FONT
+PARAM_FONT = "%s %f" % (FONT_FAMILY, FONT_SIZE - 0.5)
+
##The size of the state saving cache in the flow graph (for undo/redo functionality)
STATE_CACHE_SIZE = 42
diff --git a/grc/gui/Messages.py b/grc/gui/Messages.py
index f220b6dd06..90f508d770 100644
--- a/grc/gui/Messages.py
+++ b/grc/gui/Messages.py
@@ -24,15 +24,17 @@ import os
## A list of functions that can receive a message.
MESSENGERS_LIST = list()
+
def register_messenger(messenger):
"""
Append the given messenger to the list of messengers.
Args:
- messenger: a method thats takes a string
+ messenger: a method that takes a string
"""
MESSENGERS_LIST.append(messenger)
+
def send(message):
"""
Give the message to each of the messengers.
@@ -102,8 +104,8 @@ def send_start_exec(file_path):
def send_verbose_exec(verbose):
send(verbose)
-def send_end_exec():
- send('\n>>> Done\n')
+def send_end_exec(returncode=0):
+ send('\n>>> Done%s\n' % (" (return code %s)" % returncode if returncode else ""))
################# functions for saving flow graphs ########################################
def send_fail_save(file_path):
diff --git a/grc/gui/Param.py b/grc/gui/Param.py
index ef1c154933..2ef8603a83 100644
--- a/grc/gui/Param.py
+++ b/grc/gui/Param.py
@@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
import Utils
from Element import Element
+from . Constants import PARAM_FONT
import pygtk
pygtk.require('2.0')
import gtk
@@ -196,7 +197,7 @@ class FileParam(EntryParam):
PARAM_MARKUP_TMPL="""\
#set $foreground = $param.is_valid() and 'black' or 'red'
-<span foreground="$foreground" font_desc="Sans 7.5"><b>$encode($param.get_name()): </b>$encode(repr($param))</span>"""
+<span foreground="$foreground" font_desc="$font"><b>$encode($param.get_name()): </b>$encode(repr($param))</span>"""
PARAM_LABEL_MARKUP_TMPL="""\
#set $foreground = $modified and 'blue' or $param.is_valid() and 'black' or 'red'
@@ -261,4 +262,4 @@ class Param(Element):
Returns:
a pango markup string
"""
- return Utils.parse_template(PARAM_MARKUP_TMPL, param=self)
+ return Utils.parse_template(PARAM_MARKUP_TMPL, param=self, font=PARAM_FONT)
diff --git a/grc/gui/Port.py b/grc/gui/Port.py
index 364ca6a5b9..2a87573911 100644
--- a/grc/gui/Port.py
+++ b/grc/gui/Port.py
@@ -21,7 +21,7 @@ from Element import Element
from Constants import \
PORT_SEPARATION, CONNECTOR_EXTENSION_MINIMAL, \
CONNECTOR_EXTENSION_INCREMENT, \
- PORT_LABEL_PADDING, PORT_MIN_WIDTH, PORT_LABEL_HIDDEN_WIDTH
+ PORT_LABEL_PADDING, PORT_MIN_WIDTH, PORT_LABEL_HIDDEN_WIDTH, PORT_FONT
import Utils
import Actions
import Colors
@@ -29,10 +29,8 @@ import pygtk
pygtk.require('2.0')
import gtk
-PORT_HIDDEN_MARKUP_TMPL="""\
-<span foreground="black" font_desc="Sans 7.5"> </span>"""
PORT_MARKUP_TMPL="""\
-<span foreground="black" font_desc="Sans 7.5">$encode($port.get_name())</span>"""
+<span foreground="black" font_desc="$font">$encode($port.get_name())</span>"""
class Port(Element):
@@ -115,7 +113,7 @@ class Port(Element):
self._bg_color = Colors.get_color(self.get_color())
#create the layout
layout = gtk.DrawingArea().create_pango_layout('')
- layout.set_markup(Utils.parse_template(PORT_MARKUP_TMPL, port=self))
+ layout.set_markup(Utils.parse_template(PORT_MARKUP_TMPL, port=self, font=PORT_FONT))
self.w, self.h = layout.get_pixel_size()
self.W, self.H = 2*PORT_LABEL_PADDING + self.w, 2*PORT_LABEL_PADDING+self.h
self.H = self.modify_height(self.H)
diff --git a/grc/python/CMakeLists.txt b/grc/python/CMakeLists.txt
index 4832dd897e..41d965e89c 100644
--- a/grc/python/CMakeLists.txt
+++ b/grc/python/CMakeLists.txt
@@ -19,7 +19,6 @@
########################################################################
GR_PYTHON_INSTALL(FILES
- convert_hier.py
expr_utils.py
extract_docs.py
Block.py
diff --git a/grc/python/FlowGraph.py b/grc/python/FlowGraph.py
index daec2d4310..977200da66 100644
--- a/grc/python/FlowGraph.py
+++ b/grc/python/FlowGraph.py
@@ -58,34 +58,62 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph):
#return from cache
return self._eval_cache[my_hash]
- def get_io_signaturev(self, direction):
+ def get_hier_block_stream_io(self, direction):
"""
- Get a list of io signatures for this flow graph.
+ Get a list of stream io signatures for this flow graph.
Args:
direction: a string of 'in' or 'out'
Returns:
- a list of dicts with: type, label, vlen, size
+ a list of dicts with: type, label, vlen, size, optional
"""
- sorted_pads = {
- 'in': self.get_pad_sources(),
- 'out': self.get_pad_sinks(),
- }[direction]
- # we only want stream ports
- sorted_pads = filter(lambda b: b.get_param('type').get_evaluated() != 'message', sorted_pads);
- expanded_pads = [];
- for i in sorted_pads:
- for j in range(i.get_param('num_streams').get_evaluated()):
- expanded_pads.append(i);
- #load io signature
- return [{
- 'label': str(pad.get_param('label').get_evaluated()),
- 'type': str(pad.get_param('type').get_evaluated()),
- 'vlen': str(pad.get_param('vlen').get_value()),
- 'size': pad.get_param('type').get_opt('size'),
- 'optional': bool(pad.get_param('optional').get_evaluated()),
- } for pad in expanded_pads]
+ return filter(lambda p: p['type'] != "message",
+ self.get_hier_block_io(direction))
+
+ def get_hier_block_message_io(self, direction):
+ """
+ Get a list of message io signatures for this flow graph.
+
+ Args:
+ direction: a string of 'in' or 'out'
+
+ Returns:
+ a list of dicts with: type, label, vlen, size, optional
+ """
+ return filter(lambda p: p['type'] == "message",
+ self.get_hier_block_io(direction))
+
+ def get_hier_block_io(self, direction):
+ """
+ Get a list of io ports for this flow graph.
+
+ Args:
+ direction: a string of 'in' or 'out'
+
+ Returns:
+ a list of dicts with: type, label, vlen, size, optional
+ """
+ pads = self.get_pad_sources() if direction in ('sink', 'in') else \
+ self.get_pad_sinks() if direction in ('source', 'out') else []
+ ports = []
+ for pad in pads:
+ master = {
+ 'label': str(pad.get_param('label').get_evaluated()),
+ 'type': str(pad.get_param('type').get_evaluated()),
+ 'vlen': str(pad.get_param('vlen').get_value()),
+ 'size': pad.get_param('type').get_opt('size'),
+ 'optional': bool(pad.get_param('optional').get_evaluated()),
+ }
+ num_ports = pad.get_param('num_streams').get_evaluated()
+ if num_ports > 1:
+ for i in xrange(num_ports):
+ clone = master.copy()
+ clone['label'] += str(i)
+ ports.append(clone)
+ else:
+ ports.append(master)
+ return ports
def get_pad_sources(self):
"""
@@ -118,20 +146,14 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph):
key_offset = 0
pads = self.get_pad_sources() if port.is_source() else self.get_pad_sinks()
for pad in pads:
+ if pad.get_param('type').get_evaluated() == "message":
+ continue
if port.get_parent() == pad:
return str(key_offset + int(port.get_key()))
# assuming we have either only sources or sinks
key_offset += len(pad.get_ports())
return -1
- def get_msg_pad_sources(self):
- ps = self.get_pad_sources();
- return filter(lambda b: b.get_param('type').get_evaluated() == 'message', ps);
-
- def get_msg_pad_sinks(self):
- ps = self.get_pad_sinks();
- return filter(lambda b: b.get_param('type').get_evaluated() == 'message', ps);
-
def get_imports(self):
"""
Get a set of all import statments in this flow graph namespace.
diff --git a/grc/python/Generator.py b/grc/python/Generator.py
index 4a496b7c0f..24d943d28d 100644
--- a/grc/python/Generator.py
+++ b/grc/python/Generator.py
@@ -23,14 +23,18 @@ import subprocess
import tempfile
from distutils.spawn import find_executable
from Cheetah.Template import Template
-import expr_utils
-from Constants import \
- TOP_BLOCK_FILE_MODE, HIER_BLOCK_FILE_MODE, HIER_BLOCKS_LIB_DIR, FLOW_GRAPH_TEMPLATE, XTERM_EXECUTABLE
-import convert_hier
+
from .. gui import Messages
+from .. base import ParseXML
+from .. base import odict
+
+from . Constants import TOP_BLOCK_FILE_MODE, FLOW_GRAPH_TEMPLATE, \
+ XTERM_EXECUTABLE, HIER_BLOCK_FILE_MODE, HIER_BLOCKS_LIB_DIR, BLOCK_DTD
+from . import expr_utils
class Generator(object):
+ """Adaptor for various generators (uses generate_options)"""
def __init__(self, flow_graph, file_path):
"""
@@ -39,44 +43,67 @@ class Generator(object):
Args:
flow_graph: the flow graph object
+ file_path: the path to the grc file
+ """
+ self._generate_options = flow_graph.get_option('generate_options')
+ if self._generate_options == 'hb':
+ self._generator = HierBlockGenerator(flow_graph, file_path)
+ else:
+ self._generator = TopBlockGenerator(flow_graph, file_path)
+
+ def get_generate_options(self):
+ return self._generate_options
+
+ def __getattr__(self, item):
+ """get all other attrib from actual generator object"""
+ return getattr(self._generator, item)
+
+
+class TopBlockGenerator(object):
+
+ def __init__(self, flow_graph, file_path):
+ """
+ Initialize the top block generator object.
+
+ Args:
+ flow_graph: the flow graph object
file_path: the path to write the file to
"""
self._flow_graph = flow_graph
self._generate_options = self._flow_graph.get_option('generate_options')
- if self._generate_options == 'hb':
- self._mode = HIER_BLOCK_FILE_MODE
- dirname = HIER_BLOCKS_LIB_DIR
- else:
- self._mode = TOP_BLOCK_FILE_MODE
- dirname = os.path.dirname(file_path)
- #handle the case where the directory is read-only
- #in this case, use the system's temp directory
- if not os.access(dirname, os.W_OK):
- dirname = tempfile.gettempdir()
+ self._mode = TOP_BLOCK_FILE_MODE
+ dirname = os.path.dirname(file_path)
+ #handle the case where the directory is read-only
+ #in this case, use the system's temp directory
+ if not os.access(dirname, os.W_OK):
+ dirname = tempfile.gettempdir()
filename = self._flow_graph.get_option('id') + '.py'
self._file_path = os.path.join(dirname, filename)
- def get_file_path(self): return self._file_path
+ def get_file_path(self):
+ return self._file_path
def write(self):
+ """generate output and write it to files"""
#do throttle warning
throttling_blocks = filter(lambda b: b.throttle(), self._flow_graph.get_enabled_blocks())
if not throttling_blocks and self._generate_options != 'hb':
- Messages.send_warning('''\
-This flow graph may not have flow control: no audio or RF hardware blocks found. \
-Add a Misc->Throttle block to your flow graph to avoid CPU congestion.''')
+ Messages.send_warning("This flow graph may not have flow control: "
+ "no audio or RF hardware blocks found. "
+ "Add a Misc->Throttle block to your flow "
+ "graph to avoid CPU congestion.")
if len(throttling_blocks) > 1:
keys = set(map(lambda b: b.get_key(), throttling_blocks))
if len(keys) > 1 and 'blocks_throttle' in keys:
- Messages.send_warning('''\
-This flow graph contains a throttle block and another rate limiting block, e.g. a hardware source or sink. \
-This is usually undesired. Consider removing the throttle block.''')
+ Messages.send_warning("This flow graph contains a throttle "
+ "block and another rate limiting block, "
+ "e.g. a hardware source or sink. "
+ "This is usually undesired. Consider "
+ "removing the throttle block.")
#generate
- open(self.get_file_path(), 'w').write(str(self))
- if self._generate_options == 'hb':
- #convert hier block to xml wrapper
- convert_hier.convert_hier(self._flow_graph, self.get_file_path())
- os.chmod(self.get_file_path(), self._mode)
+ open(self.get_file_path(), 'w').write(
+ self._build_python_code_from_template()
+ )
def get_popen(self):
"""
@@ -101,10 +128,12 @@ This is usually undesired. Consider removing the throttle block.''')
if self._generate_options == 'no_gui' and xterm_executable:
cmds = [xterm_executable, '-e'] + cmds
- p = subprocess.Popen(args=cmds, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=False, universal_newlines=True)
+ p = subprocess.Popen(
+ args=cmds, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
+ shell=False, universal_newlines=True)
return p
- def __str__(self):
+ def _build_python_code_from_template(self):
"""
Convert the flow graph to python code.
@@ -119,10 +148,14 @@ This is usually undesired. Consider removing the throttle block.''')
#list of blocks not including variables and imports and parameters and disabled
def _get_block_sort_text(block):
code = block.get_make().replace(block.get_id(), ' ')
- try: code += block.get_param('notebook').get_value() #older gui markup w/ wxgui
- except: pass
- try: code += block.get_param('gui_hint').get_value() #newer gui markup w/ qtgui
- except: pass
+ try:
+ code += block.get_param('notebook').get_value() #older gui markup w/ wxgui
+ except:
+ pass
+ try:
+ code += block.get_param('gui_hint').get_value() #newer gui markup w/ qtgui
+ except:
+ pass
return code
blocks = expr_utils.sort_objects(
self._flow_graph.get_enabled_blocks(),
@@ -137,7 +170,7 @@ This is usually undesired. Consider removing the throttle block.''')
#list of variable names
var_ids = [var.get_id() for var in parameters + variables]
#prepend self.
- replace_dict = dict([(var_id, 'self.%s'%var_id) for var_id in var_ids])
+ replace_dict = dict([(var_id, 'self.%s' % var_id) for var_id in var_ids])
#list of callbacks
callbacks = [
expr_utils.expr_replace(cb, replace_dict)
@@ -155,7 +188,7 @@ This is usually undesired. Consider removing the throttle block.''')
'flow_graph': self._flow_graph,
'variables': variables,
'parameters': parameters,
- 'monitors': monitors,
+ 'monitors': monitors,
'blocks': blocks,
'connections': connections,
'messages': messages,
@@ -166,3 +199,116 @@ This is usually undesired. Consider removing the throttle block.''')
#build the template
t = Template(open(FLOW_GRAPH_TEMPLATE, 'r').read(), namespace)
return str(t)
+
+
+class HierBlockGenerator(TopBlockGenerator):
+ """Extends the top block generator to also generate a block XML file"""
+
+ def __init__(self, flow_graph, file_path):
+ """
+ Initialize the hier block generator object.
+
+ Args:
+ flow_graph: the flow graph object
+ file_path: where to write the py file (the xml goes into HIER_BLOCK_LIB_DIR)
+ """
+ TopBlockGenerator.__init__(self, flow_graph, file_path)
+ self._mode = HIER_BLOCK_FILE_MODE
+ self._file_path = os.path.join(HIER_BLOCKS_LIB_DIR,
+ self._flow_graph.get_option('id') + '.py')
+ self._file_path_xml = self._file_path + '.xml'
+
+ def get_file_path_xml(self):
+ return self._file_path_xml
+
+ def write(self):
+ """generate output and write it to files"""
+ TopBlockGenerator.write(self)
+ ParseXML.to_file(self._build_block_n_from_flow_graph_io(), self.get_file_path_xml())
+ ParseXML.validate_dtd(self.get_file_path_xml(), BLOCK_DTD)
+
+ def _build_block_n_from_flow_graph_io(self):
+ """
+ Generate a block XML nested data from the flow graph IO
+
+ Returns:
+ a xml node tree
+ """
+ #extract info from the flow graph
+ block_key = self._flow_graph.get_option('id')
+ parameters = self._flow_graph.get_parameters()
+
+ def var_or_value(name):
+ if name in map(lambda p: p.get_id(), parameters):
+ return "$"+name
+ return name
+
+ #build the nested data
+ block_n = odict()
+ block_n['name'] = self._flow_graph.get_option('title') or \
+ self._flow_graph.get_option('id').replace('_', ' ').title()
+ block_n['key'] = block_key
+ block_n['category'] = self._flow_graph.get_option('category')
+ block_n['import'] = 'execfile("{0}")'.format(self.get_file_path())
+ #make data
+ if parameters:
+ block_n['make'] = '{cls}(\n {kwargs},\n)'.format(
+ cls=block_key,
+ kwargs=',\n '.join(
+ '{key}=${key}'.format(key=param.get_id()) for param in parameters
+ ),
+ )
+ else:
+ block_n['make'] = '{cls}()'.format(cls=block_key)
+ #callback data
+ block_n['callback'] = [
+ 'set_{key}(${key})'.format(key=param.get_id()) for param in parameters
+ ]
+
+ # Parameters
+ block_n['param'] = list()
+ for param in parameters:
+ param_n = odict()
+ param_n['name'] = param.get_param('label').get_value() or param.get_id()
+ param_n['key'] = param.get_id()
+ param_n['value'] = param.get_param('value').get_value()
+ param_n['type'] = 'raw'
+ block_n['param'].append(param_n)
+
+ # bus stuff
+ if self._flow_graph.get_bussink():
+ block_n['bus_sink'] = '1'
+ if self._flow_graph.get_bussrc():
+ block_n['bus_source'] = '1'
+
+ # sink/source ports
+ for direction in ('sink', 'source'):
+ block_n[direction] = list()
+ for port in self._flow_graph.get_hier_block_io(direction):
+ port_n = odict()
+ port_n['name'] = port['label']
+ port_n['type'] = port['type']
+ if port['type'] != "message":
+ port_n['vlen'] = var_or_value(port['vlen'])
+ if port['optional']:
+ port_n['optional'] = '1'
+ block_n[direction].append(port_n)
+
+ # more bus stuff
+ bus_struct_sink = self._flow_graph.get_bus_structure_sink()
+ if bus_struct_sink:
+ block_n['bus_structure_sink'] = bus_struct_sink[0].get_param('struct').get_value()
+ bus_struct_src = self._flow_graph.get_bus_structure_src()
+ if bus_struct_src:
+ block_n['bus_structure_source'] = bus_struct_src[0].get_param('struct').get_value()
+
+ # documentation
+ block_n['doc'] = "\n".join(field for field in (
+ self._flow_graph.get_option('author'),
+ self._flow_graph.get_option('description'),
+ self.get_file_path()
+ ) if field)
+ block_n['grc_source'] = str(self._flow_graph.grc_file_path)
+
+ n = {'block': block_n}
+ return n
diff --git a/grc/python/convert_hier.py b/grc/python/convert_hier.py
deleted file mode 100644
index cf4c04a149..0000000000
--- a/grc/python/convert_hier.py
+++ /dev/null
@@ -1,116 +0,0 @@
-"""
-Copyright 2008-2011 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from Constants import BLOCK_DTD
-from .. base import ParseXML
-from .. base import odict
-
-def convert_hier(flow_graph, python_file):
- #extract info from the flow graph
- input_sigs = flow_graph.get_io_signaturev('in')
- output_sigs = flow_graph.get_io_signaturev('out')
- input_msgp = flow_graph.get_msg_pad_sources();
- output_msgp = flow_graph.get_msg_pad_sinks();
- parameters = flow_graph.get_parameters()
- bussink = flow_graph.get_bussink()
- bussrc = flow_graph.get_bussrc()
- bus_struct_sink = flow_graph.get_bus_structure_sink()
- bus_struct_src = flow_graph.get_bus_structure_src()
- block_key = flow_graph.get_option('id')
- block_name = flow_graph.get_option('title') or flow_graph.get_option('id').replace('_', ' ').title()
- block_category = flow_graph.get_option('category')
- block_desc = flow_graph.get_option('description')
- block_author = flow_graph.get_option('author')
- #build the nested data
- block_n = odict()
- block_n['name'] = block_name
- block_n['key'] = block_key
- block_n['category'] = block_category
- block_n['import'] = 'execfile("%s")'%python_file
- #make data
- if parameters: block_n['make'] = '%s(\n %s,\n)'%(
- block_key,
- ',\n '.join(['%s=$%s'%(param.get_id(), param.get_id()) for param in parameters]),
- )
- else: block_n['make'] = '%s()'%block_key
- #callback data
- block_n['callback'] = ['set_%s($%s)'%(param.get_id(), param.get_id()) for param in parameters]
- #param data
- params_n = list()
- for param in parameters:
- param_n = odict()
- param_n['name'] = param.get_param('label').get_value() or param.get_id()
- param_n['key'] = param.get_id()
- param_n['value'] = param.get_param('value').get_value()
- param_n['type'] = 'raw'
- params_n.append(param_n)
- block_n['param'] = params_n
- #sink data stream ports
- if bussink:
- block_n['bus_sink'] = '1';
- if bussrc:
- block_n['bus_source'] = '1';
- block_n['sink'] = list()
- for input_sig in input_sigs:
- sink_n = odict()
- sink_n['name'] = input_sig['label']
- sink_n['type'] = input_sig['type']
- sink_n['vlen'] = var_or_value(input_sig['vlen'], parameters)
- if input_sig['optional']: sink_n['optional'] = '1'
- block_n['sink'].append(sink_n)
- #sink data msg ports
- for input_sig in input_msgp:
- sink_n = odict()
- sink_n['name'] = input_sig.get_param("label").get_value();
- sink_n['type'] = "message"
- sink_n['optional'] = input_sig.get_param("optional").get_value();
- block_n['sink'].append(sink_n)
- #source data stream ports
- block_n['source'] = list()
- if bus_struct_sink:
- block_n['bus_structure_sink'] = bus_struct_sink[0].get_param('struct').get_value();
- if bus_struct_src:
- block_n['bus_structure_source'] = bus_struct_src[0].get_param('struct').get_value();
- for output_sig in output_sigs:
- source_n = odict()
- source_n['name'] = output_sig['label']
- source_n['type'] = output_sig['type']
- source_n['vlen'] = var_or_value(output_sig['vlen'], parameters)
- if output_sig['optional']: source_n['optional'] = '1'
- block_n['source'].append(source_n)
- #source data msg ports
- for output_sig in output_msgp:
- source_n = odict()
- source_n['name'] = output_sig.get_param("label").get_value();
- source_n['type'] = "message"
- source_n['optional'] = output_sig.get_param("optional").get_value();
- block_n['source'].append(source_n)
- #doc data
- block_n['doc'] = "%s\n%s\n%s"%(block_author, block_desc, python_file)
- block_n['grc_source'] = "%s"%(flow_graph.grc_file_path)
- #write the block_n to file
- xml_file = python_file + '.xml'
- ParseXML.to_file({'block': block_n}, xml_file)
- ParseXML.validate_dtd(xml_file, BLOCK_DTD)
-
-
-def var_or_value(name, parameters):
- if name in map(lambda p: p.get_id(), parameters):
- return "$"+name
- return name \ No newline at end of file
diff --git a/grc/python/flow_graph.tmpl b/grc/python/flow_graph.tmpl
index bee9c68af5..b07c296d09 100644
--- a/grc/python/flow_graph.tmpl
+++ b/grc/python/flow_graph.tmpl
@@ -90,8 +90,8 @@ class $(class_name)(gr.top_block):
def __init__($param_str):
gr.top_block.__init__(self, "$title")
#elif $generate_options == 'hb'
- #set $in_sigs = $flow_graph.get_io_signaturev('in')
- #set $out_sigs = $flow_graph.get_io_signaturev('out')
+ #set $in_sigs = $flow_graph.get_hier_block_stream_io('in')
+ #set $out_sigs = $flow_graph.get_hier_block_stream_io('out')
class $(class_name)(gr.hier_block2):
#def make_io_sig($io_sigs)
#set $size_strs = ['%s*%s'%(io_sig['size'], io_sig['vlen']) for io_sig in $io_sigs]
@@ -110,6 +110,12 @@ gr.io_signaturev($(len($io_sigs)), $(len($io_sigs)), [$(', '.join($size_strs))])
$make_io_sig($in_sigs),
$make_io_sig($out_sigs),
)
+ #for $pad in $flow_graph.get_hier_block_message_io('in')
+ self.message_port_register_hier_out("$pad['label']")
+ #end for
+ #for $pad in $flow_graph.get_hier_block_message_io('out')
+ self.message_port_register_hier_in("$pad['label']")
+ #end for
#end if
########################################################
##Create Parameters
@@ -208,11 +214,11 @@ gr.io_signaturev($(len($io_sigs)), $(len($io_sigs)), [$(', '.join($size_strs))])
#end for
########################################################
-##Create Asynch Message Connections
+##Create Message Connections
########################################################
#if $messages2
$DIVIDER
- # Asynch Message Connections
+ # Message Connections
$DIVIDER
#end if
#for $msg in $messages2
diff --git a/volk/apps/volk_profile.cc b/volk/apps/volk_profile.cc
index 074d1e7be4..9bc1842c63 100644
--- a/volk/apps/volk_profile.cc
+++ b/volk/apps/volk_profile.cc
@@ -37,6 +37,49 @@
namespace fs = boost::filesystem;
+void write_json(std::ofstream &json_file, std::vector<volk_test_results_t> results) {
+ json_file << "{" << std::endl;
+ json_file << " \"volk_tests\": [" << std::endl;
+ size_t len = results.size();
+ size_t i = 0;
+ BOOST_FOREACH(volk_test_results_t &result, results) {
+ json_file << " {" << std::endl;
+ json_file << " \"name\": \"" << result.name << "\"," << std::endl;
+ json_file << " \"vlen\": " << result.vlen << "," << std::endl;
+ json_file << " \"iter\": " << result.iter << "," << std::endl;
+ json_file << " \"best_arch_a\": \"" << result.best_arch_a
+ << "\"," << std::endl;
+ json_file << " \"best_arch_u\": \"" << result.best_arch_u
+ << "\"," << std::endl;
+ json_file << " \"results\": {" << std::endl;
+ size_t results_len = result.results.size();
+ size_t ri = 0;
+ typedef std::pair<std::string, volk_test_time_t> tpair;
+ BOOST_FOREACH(tpair pair, result.results) {
+ volk_test_time_t time = pair.second;
+ json_file << " \"" << time.name << "\": {" << std::endl;
+ json_file << " \"name\": \"" << time.name << "\"," << std::endl;
+ json_file << " \"time\": " << time.time << "," << std::endl;
+ json_file << " \"units\": \"" << time.units << "\"" << std::endl;
+ json_file << " }" ;
+ if(ri+1 != results_len) {
+ json_file << ",";
+ }
+ json_file << std::endl;
+ ri++;
+ }
+ json_file << " }" << std::endl;
+ json_file << " }";
+ if(i+1 != len) {
+ json_file << ",";
+ }
+ json_file << std::endl;
+ i++;
+ }
+ json_file << " ]" << std::endl;
+ json_file << "}" << std::endl;
+}
+
int main(int argc, char *argv[]) {
// Adding program options
boost::program_options::options_description desc("Options");
@@ -49,6 +92,9 @@ int main(int argc, char *argv[]) {
("tests-regex,R",
boost::program_options::value<std::string>(),
"Run tests matching regular expression.")
+ ("json,j",
+ boost::program_options::value<std::string>(),
+ "JSON output file")
;
// Handle the options that were given
@@ -56,6 +102,8 @@ int main(int argc, char *argv[]) {
bool benchmark_mode;
std::string kernel_regex;
bool store_results = true;
+ std::ofstream json_file;
+
try {
boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
boost::program_options::notify(vm);
@@ -83,9 +131,14 @@ int main(int argc, char *argv[]) {
return 0;
}
+ if ( vm.count("json") )
+ {
+ json_file.open( vm["json"].as<std::string>().c_str() );
+ }
+
// Run tests
- std::vector<std::string> results;
+ std::vector<volk_test_results_t> results;
//VOLK_PROFILE(volk_16i_x5_add_quad_16i_x4, 1e-4, 2046, 10000, &results, benchmark_mode, kernel_regex);
//VOLK_PROFILE(volk_16i_branch_4_state_8, 1e-4, 2046, 10000, &results, benchmark_mode, kernel_regex);
@@ -104,16 +157,25 @@ int main(int argc, char *argv[]) {
//VOLK_PROFILE(volk_16i_max_star_horizontal_16i, 0, 0, 204602, 10000, &results, benchmark_mode, kernel_regex);
//VOLK_PROFILE(volk_16i_permute_and_scalar_add, 1e-4, 0, 2046, 10000, &results, benchmark_mode, kernel_regex);
//VOLK_PROFILE(volk_16i_x4_quad_max_star_16i, 1e-4, 0, 2046, 10000, &results, benchmark_mode, kernel_regex);
- VOLK_PROFILE(volk_16u_byteswap, 0, 0, 204602, 10000, &results, benchmark_mode, kernel_regex);
+ VOLK_PUPPET_PROFILE(volk_16u_byteswappuppet_16u, volk_16u_byteswap, 0, 0, 204602, 10000, &results, benchmark_mode, kernel_regex);
VOLK_PROFILE(volk_16i_32fc_dot_prod_32fc, 1e-4, 0, 204602, 10000, &results, benchmark_mode, kernel_regex);
VOLK_PROFILE(volk_32f_accumulator_s32f, 1e-4, 0, 204602, 10000, &results, benchmark_mode, kernel_regex);
VOLK_PROFILE(volk_32f_x2_add_32f, 1e-4, 0, 204602, 10000, &results, benchmark_mode, kernel_regex);
VOLK_PROFILE(volk_32fc_32f_multiply_32fc, 1e-4, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_32f_log2_32f, 1.5e-1, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_32f_expfast_32f, 1e-1, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_32f_x2_pow_32f, 1e-2, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_32f_sin_32f, 1e-6, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_32f_cos_32f, 1e-6, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_32f_tan_32f, 1e-6, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_32f_atan_32f, 1e-3, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_32f_asin_32f, 1e-3, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_32f_acos_32f, 1e-3, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
VOLK_PROFILE(volk_32fc_s32f_power_32fc, 1e-4, 0, 204602, 50, &results, benchmark_mode, kernel_regex);
VOLK_PROFILE(volk_32f_s32f_calc_spectral_noise_floor_32f, 1e-4, 20.0, 204602, 1000, &results, benchmark_mode, kernel_regex);
VOLK_PROFILE(volk_32fc_s32f_atan2_32f, 1e-4, 10.0, 204602, 100, &results, benchmark_mode, kernel_regex);
//VOLK_PROFILE(volk_32fc_x2_conjugate_dot_prod_32fc, 1e-4, 0, 2046, 10000, &results, benchmark_mode, kernel_regex);
- VOLK_PROFILE(volk_32fc_x2_conjugate_dot_prod_32fc, 1e-4, 0, 204602, 10000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_32fc_x2_conjugate_dot_prod_32fc, 1e-4, 0, 204602, 100, &results, benchmark_mode, kernel_regex);
VOLK_PROFILE(volk_32fc_deinterleave_32f_x2, 1e-4, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
VOLK_PROFILE(volk_32fc_deinterleave_64f_x2, 1e-4, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
VOLK_PROFILE(volk_32fc_s32f_deinterleave_real_16i, 0, 32768, 204602, 10000, &results, benchmark_mode, kernel_regex);
@@ -157,13 +219,13 @@ int main(int argc, char *argv[]) {
VOLK_PROFILE(volk_32i_x2_and_32i, 0, 0, 204602, 10000, &results, benchmark_mode, kernel_regex);
VOLK_PROFILE(volk_32i_s32f_convert_32f, 1e-4, 100, 204602, 10000, &results, benchmark_mode, kernel_regex);
VOLK_PROFILE(volk_32i_x2_or_32i, 0, 0, 204602, 10000, &results, benchmark_mode, kernel_regex);
- VOLK_PROFILE(volk_32u_byteswap, 0, 0, 204602, 2000, &results, benchmark_mode, kernel_regex);
- //VOLK_PROFILE(volk_32u_popcnt, 0, 0, 2046, 10000, &results, benchmark_mode, kernel_regex);
+ VOLK_PUPPET_PROFILE(volk_32u_byteswappuppet_32u, volk_32u_byteswap, 0, 0, 204602, 2000, &results, benchmark_mode, kernel_regex);
+ VOLK_PUPPET_PROFILE(volk_32u_popcntpuppet_32u, volk32u_popcnt_32u, 0, 0, 2046, 10000, &results, benchmark_mode, kernel_regex);
VOLK_PROFILE(volk_64f_convert_32f, 1e-4, 0, 204602, 10000, &results, benchmark_mode, kernel_regex);
VOLK_PROFILE(volk_64f_x2_max_64f, 1e-4, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
VOLK_PROFILE(volk_64f_x2_min_64f, 1e-4, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
- VOLK_PROFILE(volk_64u_byteswap, 0, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
- //VOLK_PROFILE(volk_64u_popcnt, 0, 0, 2046, 10000, &results, benchmark_mode, kernel_regex);
+ VOLK_PUPPET_PROFILE(volk_64u_byteswappuppet_64u, volk_64u_byteswap, 0, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
+ VOLK_PUPPET_PROFILE(volk_64u_popcntpuppet_64u, volk_64u_popcnt, 0, 0, 2046, 10000, &results, benchmark_mode, kernel_regex);
VOLK_PROFILE(volk_8ic_deinterleave_16i_x2, 0, 0, 204602, 3000, &results, benchmark_mode, kernel_regex);
VOLK_PROFILE(volk_8ic_s32f_deinterleave_32f_x2, 1e-4, 100, 204602, 3000, &results, benchmark_mode, kernel_regex);
VOLK_PROFILE(volk_8ic_deinterleave_real_16i, 0, 256, 204602, 3000, &results, benchmark_mode, kernel_regex);
@@ -178,6 +240,7 @@ int main(int argc, char *argv[]) {
VOLK_PROFILE(volk_32f_s32f_multiply_32f, 1e-4, 1.0, 204602, 10000, &results, benchmark_mode, kernel_regex);
VOLK_PROFILE(volk_32f_binary_slicer_32i, 0, 1.0, 204602, 10000, &results, benchmark_mode, kernel_regex);
VOLK_PROFILE(volk_32f_binary_slicer_8i, 0, 1.0, 204602, 10000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_32f_tanh_32f, 1e-6, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
// Until we can update the config on a kernel by kernel basis
// do not overwrite volk_config when using a regex.
@@ -204,8 +267,10 @@ int main(int argc, char *argv[]) {
#the function name is followed by the preferred architecture.\n\
";
- BOOST_FOREACH(std::string result, results) {
- config << result << std::endl;
+ BOOST_FOREACH(volk_test_results_t result, results) {
+ config << result.config_name << " "
+ << result.best_arch_a << " "
+ << result.best_arch_u << std::endl;
}
config.close();
}
diff --git a/volk/kernels/volk/volk_16i_32fc_dot_prod_32fc.h b/volk/kernels/volk/volk_16i_32fc_dot_prod_32fc.h
index 8c66892fd9..2656d766b8 100644
--- a/volk/kernels/volk/volk_16i_32fc_dot_prod_32fc.h
+++ b/volk/kernels/volk/volk_16i_32fc_dot_prod_32fc.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_16i_32fc_dot_prod_32fc_H
#define INCLUDED_volk_16i_32fc_dot_prod_32fc_H
@@ -7,7 +29,6 @@
#ifdef LV_HAVE_GENERIC
-
static inline void volk_16i_32fc_dot_prod_32fc_generic(lv_32fc_t* result, const short* input, const lv_32fc_t * taps, unsigned int num_points) {
static const int N_UNROLL = 4;
@@ -36,7 +57,54 @@ static inline void volk_16i_32fc_dot_prod_32fc_generic(lv_32fc_t* result, const
#endif /*LV_HAVE_GENERIC*/
+#ifdef LV_HAVE_NEON
+#include <arm_neon.h>
+static inline void volk_16i_32fc_dot_prod_32fc_neon(lv_32fc_t* result, const short* input, const lv_32fc_t * taps, unsigned int num_points) {
+
+ unsigned ii;
+ unsigned quarter_points = num_points / 4;
+ lv_32fc_t* tapsPtr = (lv_32fc_t*) taps;
+ short* inputPtr = (short*) input;
+ lv_32fc_t accumulator_vec[4];
+
+ float32x4x2_t tapsVal, accumulator_val;
+ int16x4_t input16;
+ int32x4_t input32;
+ float32x4_t input_float, prod_re, prod_im;
+
+ accumulator_val.val[0] = vdupq_n_f32(0.0);
+ accumulator_val.val[1] = vdupq_n_f32(0.0);
+
+ for(ii = 0; ii < quarter_points; ++ii) {
+ tapsVal = vld2q_f32((float*)tapsPtr);
+ input16 = vld1_s16(inputPtr);
+ // widen 16-bit int to 32-bit int
+ input32 = vmovl_s16(input16);
+ // convert 32-bit int to float with scale
+ input_float = vcvtq_f32_s32(input32);
+
+ prod_re = vmulq_f32(input_float, tapsVal.val[0]);
+ prod_im = vmulq_f32(input_float, tapsVal.val[1]);
+
+ accumulator_val.val[0] = vaddq_f32(prod_re, accumulator_val.val[0]);
+ accumulator_val.val[1] = vaddq_f32(prod_im, accumulator_val.val[1]);
+
+ tapsPtr += 4;
+ inputPtr += 4;
+ }
+ vst2q_f32((float*)accumulator_vec, accumulator_val);
+ accumulator_vec[0] += accumulator_vec[1];
+ accumulator_vec[2] += accumulator_vec[3];
+ accumulator_vec[0] += accumulator_vec[2];
+
+ for(ii = quarter_points * 4; ii < num_points; ++ii) {
+ accumulator_vec[0] += *(tapsPtr++) * (float)(*(inputPtr++));
+ }
+
+ *result = accumulator_vec[0];
+}
+#endif /*LV_HAVE_NEON*/
#if LV_HAVE_SSE && LV_HAVE_MMX
diff --git a/volk/kernels/volk/volk_16i_branch_4_state_8.h b/volk/kernels/volk/volk_16i_branch_4_state_8.h
index cdfbc7ba13..4477245bbf 100644
--- a/volk/kernels/volk/volk_16i_branch_4_state_8.h
+++ b/volk/kernels/volk/volk_16i_branch_4_state_8.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_16i_branch_4_state_8_a_H
#define INCLUDED_volk_16i_branch_4_state_8_a_H
diff --git a/volk/kernels/volk/volk_16i_convert_8i.h b/volk/kernels/volk/volk_16i_convert_8i.h
index 3789b2e4ab..6f16fa45d3 100644
--- a/volk/kernels/volk/volk_16i_convert_8i.h
+++ b/volk/kernels/volk/volk_16i_convert_8i.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_16i_convert_8i_u_H
#define INCLUDED_volk_16i_convert_8i_u_H
@@ -116,6 +138,46 @@ static inline void volk_16i_convert_8i_a_sse2(int8_t* outputVector, const int16_
}
#endif /* LV_HAVE_SSE2 */
+#ifdef LV_HAVE_NEON
+#include <arm_neon.h>
+/*!
+ \brief Converts the input 16 bit integer data into 8 bit integer data
+ \param inputVector The 16 bit input data buffer
+ \param outputVector The 8 bit output data buffer
+ \param num_points The number of data values to be converted
+*/
+static inline void volk_16i_convert_8i_neon(int8_t* outputVector, const int16_t* inputVector, unsigned int num_points){
+ int8_t* outputVectorPtr = outputVector;
+ const int16_t* inputVectorPtr = inputVector;
+ unsigned int number = 0;
+ unsigned int sixteenth_points = num_points / 16;
+
+ int16x8_t inputVal0;
+ int16x8_t inputVal1;
+ int8x8_t outputVal0;
+ int8x8_t outputVal1;
+ int8x16_t outputVal;
+
+ for(number = 0; number < sixteenth_points; number++){
+ // load two input vectors
+ inputVal0 = vld1q_s16(inputVectorPtr);
+ inputVal1 = vld1q_s16(inputVectorPtr+8);
+ // shift right
+ outputVal0 = vshrn_n_s16(inputVal0, 8);
+ outputVal1 = vshrn_n_s16(inputVal1, 8);
+ // squash two vectors and write output
+ outputVal = vcombine_s8(outputVal0, outputVal1);
+ vst1q_s8(outputVectorPtr, outputVal);
+ inputVectorPtr += 16;
+ outputVectorPtr += 16;
+ }
+
+ for(number = sixteenth_points * 16; number < num_points; number++){
+ *outputVectorPtr++ = ((int8_t)(*inputVectorPtr++ >> 8));
+ }
+}
+#endif /* LV_HAVE_NEON */
+
#ifdef LV_HAVE_GENERIC
/*!
\brief Converts the input 16 bit integer data into 8 bit integer data
@@ -134,7 +196,4 @@ static inline void volk_16i_convert_8i_a_generic(int8_t* outputVector, const int
}
#endif /* LV_HAVE_GENERIC */
-
-
-
#endif /* INCLUDED_volk_16i_convert_8i_a_H */
diff --git a/volk/kernels/volk/volk_16i_max_star_16i.h b/volk/kernels/volk/volk_16i_max_star_16i.h
index d296c43cb0..e81a91a375 100644
--- a/volk/kernels/volk/volk_16i_max_star_16i.h
+++ b/volk/kernels/volk/volk_16i_max_star_16i.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_16i_max_star_16i_a_H
#define INCLUDED_volk_16i_max_star_16i_a_H
@@ -94,7 +116,7 @@ static inline void volk_16i_max_star_16i_neon(short* target, short* src0, unsign
int16x8_t diff, zeros;
uint16x8_t comp1, comp2;
zeros = veorq_s16(zeros, zeros);
-
+
int16x8x2_t tmpvec;
int16x8_t candidate_vec = vld1q_dup_s16(src0 );
diff --git a/volk/kernels/volk/volk_16i_max_star_horizontal_16i.h b/volk/kernels/volk/volk_16i_max_star_horizontal_16i.h
index 1915522947..b671929a29 100644
--- a/volk/kernels/volk/volk_16i_max_star_horizontal_16i.h
+++ b/volk/kernels/volk/volk_16i_max_star_horizontal_16i.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_16i_max_star_horizontal_16i_a_H
#define INCLUDED_volk_16i_max_star_horizontal_16i_a_H
@@ -125,17 +147,17 @@ static inline void volk_16i_max_star_horizontal_16i_neon(int16_t* target, int16_
diff = vsubq_s16(input_vec.val[0], input_vec.val[1]);
comp1 = vcgeq_s16(diff, zeros);
comp2 = vcltq_s16(diff, zeros);
-
+
input_vec.val[0] = vandq_s16(input_vec.val[0], (int16x8_t)comp1);
input_vec.val[1] = vandq_s16(input_vec.val[1], (int16x8_t)comp2);
-
+
max_vec = vaddq_s16(input_vec.val[0], input_vec.val[1]);
vst1q_s16(target, max_vec);
src0 += 16;
target += 8;
}
for(number=0; number < num_points%16; number+=2) {
- target[number >> 1] = ((int16_t)(src0[number] - src0[number + 1]) > 0) ? src0[number] : src0[number+1];
+ target[number >> 1] = ((int16_t)(src0[number] - src0[number + 1]) > 0) ? src0[number] : src0[number+1];
}
}
diff --git a/volk/kernels/volk/volk_16i_permute_and_scalar_add.h b/volk/kernels/volk/volk_16i_permute_and_scalar_add.h
index 7a01d172a3..e6f20b72bc 100644
--- a/volk/kernels/volk/volk_16i_permute_and_scalar_add.h
+++ b/volk/kernels/volk/volk_16i_permute_and_scalar_add.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_16i_permute_and_scalar_add_a_H
#define INCLUDED_volk_16i_permute_and_scalar_add_a_H
diff --git a/volk/kernels/volk/volk_16i_s32f_convert_32f.h b/volk/kernels/volk/volk_16i_s32f_convert_32f.h
index a810a601a0..6ea28f0e90 100644
--- a/volk/kernels/volk/volk_16i_s32f_convert_32f.h
+++ b/volk/kernels/volk/volk_16i_s32f_convert_32f.h
@@ -1,9 +1,88 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_16i_s32f_convert_32f_u_H
#define INCLUDED_volk_16i_s32f_convert_32f_u_H
#include <inttypes.h>
#include <stdio.h>
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+
+ /*!
+ \brief Converts the input 16 bit integer data into floating point data, and divides the each floating point output data point by the scalar value
+ \param inputVector The 16 bit input data buffer
+ \param outputVector The floating point output data buffer
+ \param scalar The value divided against each point in the output buffer
+ \param num_points The number of data values to be converted
+ */
+static inline void volk_16i_s32f_convert_32f_u_avx(float* outputVector, const int16_t* inputVector, const float scalar, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int eighthPoints = num_points / 8;
+
+ float* outputVectorPtr = outputVector;
+ __m128 invScalar = _mm_set_ps1(1.0/scalar);
+ int16_t* inputPtr = (int16_t*)inputVector;
+ __m128i inputVal, inputVal2;
+ __m128 ret;
+ __m256 output;
+ __m256 dummy = _mm256_setzero_ps();
+
+ for(;number < eighthPoints; number++){
+
+ // Load the 8 values
+ //inputVal = _mm_loadu_si128((__m128i*)inputPtr);
+ inputVal = _mm_loadu_si128((__m128i*)inputPtr);
+
+ // Shift the input data to the right by 64 bits ( 8 bytes )
+ inputVal2 = _mm_srli_si128(inputVal, 8);
+
+ // Convert the lower 4 values into 32 bit words
+ inputVal = _mm_cvtepi16_epi32(inputVal);
+ inputVal2 = _mm_cvtepi16_epi32(inputVal2);
+
+ ret = _mm_cvtepi32_ps(inputVal);
+ ret = _mm_mul_ps(ret, invScalar);
+ output = _mm256_insertf128_ps(dummy, ret, 0);
+
+ ret = _mm_cvtepi32_ps(inputVal2);
+ ret = _mm_mul_ps(ret, invScalar);
+ output = _mm256_insertf128_ps(output, ret, 1);
+
+ _mm256_storeu_ps(outputVectorPtr, output);
+
+ outputVectorPtr += 8;
+
+ inputPtr += 8;
+ }
+
+ number = eighthPoints * 8;
+ for(; number < num_points; number++){
+ outputVector[number] =((float)(inputVector[number])) / scalar;
+ }
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_SSE4_1
#include <smmintrin.h>
@@ -116,7 +195,53 @@ static inline void volk_16i_s32f_convert_32f_generic(float* outputVector, const
}
#endif /* LV_HAVE_GENERIC */
+#ifdef LV_HAVE_NEON
+ /*!
+ \brief Converts the input 16 bit integer data into floating point data, and divides the each floating point output data point by the scalar value
+ \param inputVector The 16 bit input data buffer
+ \param outputVector The floating point output data buffer
+ \param scalar The value divided against each point in the output buffer
+ \param num_points The number of data values to be converted
+ \note Output buffer does NOT need to be properly aligned
+ */
+static inline void volk_16i_s32f_convert_32f_neon(float* outputVector, const int16_t* inputVector, const float scalar, unsigned int num_points){
+ float* outputPtr = outputVector;
+ const int16_t* inputPtr = inputVector;
+ unsigned int number = 0;
+ unsigned int eighth_points = num_points / 8;
+
+ int16x4x2_t input16;
+ int32x4_t input32_0, input32_1;
+ float32x4_t input_float_0, input_float_1;
+ float32x4x2_t output_float;
+ float32x4_t inv_scale;
+
+ inv_scale = vdupq_n_f32(1.0/scalar);
+
+ // the generic disassembles to a 128-bit load
+ // and duplicates every instruction to operate on 64-bits
+ // at a time. This is only possible with lanes, which is faster
+ // than just doing a vld1_s16, but still slower.
+ for(number = 0; number < eighth_points; number++){
+ input16 = vld2_s16(inputPtr);
+ // widen 16-bit int to 32-bit int
+ input32_0 = vmovl_s16(input16.val[0]);
+ input32_1 = vmovl_s16(input16.val[1]);
+ // convert 32-bit int to float with scale
+ input_float_0 = vcvtq_f32_s32(input32_0);
+ input_float_1 = vcvtq_f32_s32(input32_1);
+ output_float.val[0] = vmulq_f32(input_float_0, inv_scale);
+ output_float.val[1] = vmulq_f32(input_float_1, inv_scale);
+ vst2q_f32(outputPtr, output_float);
+ inputPtr += 8;
+ outputPtr += 8;
+ }
+ for(number = eighth_points*8; number < num_points; number++){
+ *outputPtr++ = ((float)(*inputPtr++)) / scalar;
+ }
+}
+#endif /* LV_HAVE_NEON */
#endif /* INCLUDED_volk_16i_s32f_convert_32f_u_H */
@@ -126,6 +251,63 @@ static inline void volk_16i_s32f_convert_32f_generic(float* outputVector, const
#include <inttypes.h>
#include <stdio.h>
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+
+ /*!
+ \brief Converts the input 16 bit integer data into floating point data, and divides the each floating point output data point by the scalar value
+ \param inputVector The 16 bit input data buffer
+ \param outputVector The floating point output data buffer
+ \param scalar The value divided against each point in the output buffer
+ \param num_points The number of data values to be converted
+ */
+static inline void volk_16i_s32f_convert_32f_a_avx(float* outputVector, const int16_t* inputVector, const float scalar, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int eighthPoints = num_points / 8;
+
+ float* outputVectorPtr = outputVector;
+ __m128 invScalar = _mm_set_ps1(1.0/scalar);
+ int16_t* inputPtr = (int16_t*)inputVector;
+ __m128i inputVal, inputVal2;
+ __m128 ret;
+ __m256 output;
+ __m256 dummy = _mm256_setzero_ps();
+
+ for(;number < eighthPoints; number++){
+
+ // Load the 8 values
+ //inputVal = _mm_loadu_si128((__m128i*)inputPtr);
+ inputVal = _mm_load_si128((__m128i*)inputPtr);
+
+ // Shift the input data to the right by 64 bits ( 8 bytes )
+ inputVal2 = _mm_srli_si128(inputVal, 8);
+
+ // Convert the lower 4 values into 32 bit words
+ inputVal = _mm_cvtepi16_epi32(inputVal);
+ inputVal2 = _mm_cvtepi16_epi32(inputVal2);
+
+ ret = _mm_cvtepi32_ps(inputVal);
+ ret = _mm_mul_ps(ret, invScalar);
+ output = _mm256_insertf128_ps(dummy, ret, 0);
+
+ ret = _mm_cvtepi32_ps(inputVal2);
+ ret = _mm_mul_ps(ret, invScalar);
+ output = _mm256_insertf128_ps(output, ret, 1);
+
+ _mm256_store_ps(outputVectorPtr, output);
+
+ outputVectorPtr += 8;
+
+ inputPtr += 8;
+ }
+
+ number = eighthPoints * 8;
+ for(; number < num_points; number++){
+ outputVector[number] =((float)(inputVector[number])) / scalar;
+ }
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_SSE4_1
#include <smmintrin.h>
diff --git a/volk/kernels/volk/volk_16i_x4_quad_max_star_16i.h b/volk/kernels/volk/volk_16i_x4_quad_max_star_16i.h
index 8e84b6ea17..4c67ef4e7d 100644
--- a/volk/kernels/volk/volk_16i_x4_quad_max_star_16i.h
+++ b/volk/kernels/volk/volk_16i_x4_quad_max_star_16i.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_16i_x4_quad_max_star_16i_a_H
#define INCLUDED_volk_16i_x4_quad_max_star_16i_a_H
diff --git a/volk/kernels/volk/volk_16i_x5_add_quad_16i_x4.h b/volk/kernels/volk/volk_16i_x5_add_quad_16i_x4.h
index cd1952bccb..6a056ff69a 100644
--- a/volk/kernels/volk/volk_16i_x5_add_quad_16i_x4.h
+++ b/volk/kernels/volk/volk_16i_x5_add_quad_16i_x4.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_16i_x5_add_quad_16i_x4_a_H
#define INCLUDED_volk_16i_x5_add_quad_16i_x4_a_H
diff --git a/volk/kernels/volk/volk_16ic_deinterleave_16i_x2.h b/volk/kernels/volk/volk_16ic_deinterleave_16i_x2.h
index 9ce8012640..26521e215d 100644
--- a/volk/kernels/volk/volk_16ic_deinterleave_16i_x2.h
+++ b/volk/kernels/volk/volk_16ic_deinterleave_16i_x2.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_16ic_deinterleave_16i_x2_a_H
#define INCLUDED_volk_16ic_deinterleave_16i_x2_a_H
diff --git a/volk/kernels/volk/volk_16ic_deinterleave_real_16i.h b/volk/kernels/volk/volk_16ic_deinterleave_real_16i.h
index f6eccd77ee..5c2988743c 100644
--- a/volk/kernels/volk/volk_16ic_deinterleave_real_16i.h
+++ b/volk/kernels/volk/volk_16ic_deinterleave_real_16i.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_16ic_deinterleave_real_16i_a_H
#define INCLUDED_volk_16ic_deinterleave_real_16i_a_H
diff --git a/volk/kernels/volk/volk_16ic_deinterleave_real_8i.h b/volk/kernels/volk/volk_16ic_deinterleave_real_8i.h
index f3d0c83524..b2b1e2a41d 100644
--- a/volk/kernels/volk/volk_16ic_deinterleave_real_8i.h
+++ b/volk/kernels/volk/volk_16ic_deinterleave_real_8i.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_16ic_deinterleave_real_8i_a_H
#define INCLUDED_volk_16ic_deinterleave_real_8i_a_H
diff --git a/volk/kernels/volk/volk_16ic_magnitude_16i.h b/volk/kernels/volk/volk_16ic_magnitude_16i.h
index b33306a123..fb29bfdc94 100644
--- a/volk/kernels/volk/volk_16ic_magnitude_16i.h
+++ b/volk/kernels/volk/volk_16ic_magnitude_16i.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_16ic_magnitude_16i_a_H
#define INCLUDED_volk_16ic_magnitude_16i_a_H
diff --git a/volk/kernels/volk/volk_16ic_s32f_deinterleave_32f_x2.h b/volk/kernels/volk/volk_16ic_s32f_deinterleave_32f_x2.h
index 55243b4aa8..cc702de872 100644
--- a/volk/kernels/volk/volk_16ic_s32f_deinterleave_32f_x2.h
+++ b/volk/kernels/volk/volk_16ic_s32f_deinterleave_32f_x2.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_16ic_s32f_deinterleave_32f_x2_a_H
#define INCLUDED_volk_16ic_s32f_deinterleave_32f_x2_a_H
diff --git a/volk/kernels/volk/volk_16ic_s32f_deinterleave_real_32f.h b/volk/kernels/volk/volk_16ic_s32f_deinterleave_real_32f.h
index 57d078a595..2dd9188c5f 100644
--- a/volk/kernels/volk/volk_16ic_s32f_deinterleave_real_32f.h
+++ b/volk/kernels/volk/volk_16ic_s32f_deinterleave_real_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_16ic_s32f_deinterleave_real_32f_a_H
#define INCLUDED_volk_16ic_s32f_deinterleave_real_32f_a_H
diff --git a/volk/kernels/volk/volk_16ic_s32f_magnitude_32f.h b/volk/kernels/volk/volk_16ic_s32f_magnitude_32f.h
index 27901cb9ac..ba06450312 100644
--- a/volk/kernels/volk/volk_16ic_s32f_magnitude_32f.h
+++ b/volk/kernels/volk/volk_16ic_s32f_magnitude_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_16ic_s32f_magnitude_32f_a_H
#define INCLUDED_volk_16ic_s32f_magnitude_32f_a_H
diff --git a/volk/kernels/volk/volk_16u_byteswap.h b/volk/kernels/volk/volk_16u_byteswap.h
index 436caf0474..3b2f9e2c91 100644
--- a/volk/kernels/volk/volk_16u_byteswap.h
+++ b/volk/kernels/volk/volk_16u_byteswap.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_16u_byteswap_u_H
#define INCLUDED_volk_16u_byteswap_u_H
@@ -136,6 +158,58 @@ static inline void volk_16u_byteswap_neon(uint16_t* intsToSwap, unsigned int num
}
#endif /* LV_HAVE_NEON */
+#ifdef LV_HAVE_NEON
+#include <arm_neon.h>
+/*!
+ \brief Byteswaps (in-place) an aligned vector of int32_t's.
+ \param intsToSwap The vector of data to byte swap
+ \param numDataPoints The number of data points
+*/
+static inline void volk_16u_byteswap_neon_table(uint16_t* intsToSwap, unsigned int num_points){
+ uint16_t* inputPtr = intsToSwap;
+ unsigned int number = 0;
+ unsigned int n16points = num_points / 16;
+
+ uint8x8x4_t input_table;
+ uint8x8_t int_lookup01, int_lookup23, int_lookup45, int_lookup67;
+ uint8x8_t swapped_int01, swapped_int23, swapped_int45, swapped_int67;
+
+ /* these magic numbers are used as byte-indeces in the LUT.
+ they are pre-computed to save time. A simple C program
+ can calculate them; for example for lookup01:
+ uint8_t chars[8] = {24, 16, 8, 0, 25, 17, 9, 1};
+ for(ii=0; ii < 8; ++ii) {
+ index += ((uint64_t)(*(chars+ii))) << (ii*8);
+ }
+ */
+ int_lookup01 = vcreate_u8(1232017111498883080);
+ int_lookup23 = vcreate_u8(1376697457175036426);
+ int_lookup45 = vcreate_u8(1521377802851189772);
+ int_lookup67 = vcreate_u8(1666058148527343118);
+
+ for(number = 0; number < n16points; ++number){
+ input_table = vld4_u8((uint8_t*) inputPtr);
+ swapped_int01 = vtbl4_u8(input_table, int_lookup01);
+ swapped_int23 = vtbl4_u8(input_table, int_lookup23);
+ swapped_int45 = vtbl4_u8(input_table, int_lookup45);
+ swapped_int67 = vtbl4_u8(input_table, int_lookup67);
+ vst1_u8((uint8_t*)inputPtr, swapped_int01);
+ vst1_u8((uint8_t*)(inputPtr+4), swapped_int23);
+ vst1_u8((uint8_t*)(inputPtr+8), swapped_int45);
+ vst1_u8((uint8_t*)(inputPtr+12), swapped_int67);
+
+ inputPtr += 16;
+ }
+
+ for(number = n16points * 16; number < num_points; ++number){
+ uint16_t output = *inputPtr;
+ output = (((output >> 8) & 0xff) | ((output << 8) & 0xff00));
+ *inputPtr = output;
+ inputPtr++;
+ }
+}
+#endif /* LV_HAVE_NEON */
+
#ifdef LV_HAVE_GENERIC
/*!
\brief Byteswaps (in-place) an aligned vector of int16_t's.
diff --git a/volk/kernels/volk/volk_16u_byteswappuppet_16u.h b/volk/kernels/volk/volk_16u_byteswappuppet_16u.h
new file mode 100644
index 0000000000..74745d328c
--- /dev/null
+++ b/volk/kernels/volk/volk_16u_byteswappuppet_16u.h
@@ -0,0 +1,55 @@
+#ifndef INCLUDED_volk_16u_byteswappuppet_16u_H
+#define INCLUDED_volk_16u_byteswappuppet_16u_H
+
+
+#include <stdint.h>
+#include <volk/volk_16u_byteswap.h>
+#include <string.h>
+
+#ifdef LV_HAVE_GENERIC
+static inline void volk_16u_byteswappuppet_16u_generic(uint16_t*output, uint16_t* intsToSwap, unsigned int num_points){
+
+ volk_16u_byteswap_generic((uint16_t*)intsToSwap, num_points);
+ memcpy((void*)output, (void*)intsToSwap, num_points * sizeof(uint16_t));
+
+}
+#endif
+
+#ifdef LV_HAVE_NEON
+static inline void volk_16u_byteswappuppet_16u_neon(uint16_t*output, uint16_t* intsToSwap, unsigned int num_points){
+
+ volk_16u_byteswap_neon((uint16_t*)intsToSwap, num_points);
+ memcpy((void*)output, (void*)intsToSwap, num_points * sizeof(uint16_t));
+
+}
+#endif
+
+#ifdef LV_HAVE_NEON
+static inline void volk_16u_byteswappuppet_16u_neon_table(uint16_t*output, uint16_t* intsToSwap, unsigned int num_points){
+
+ volk_16u_byteswap_neon_table((uint16_t*)intsToSwap, num_points);
+ memcpy((void*)output, (void*)intsToSwap, num_points * sizeof(uint16_t));
+
+}
+#endif
+
+#ifdef LV_HAVE_SSE2
+static inline void volk_16u_byteswappuppet_16u_u_sse2(uint16_t *output, uint16_t* intsToSwap, unsigned int num_points){
+
+ volk_16u_byteswap_u_sse2((uint16_t*)intsToSwap, num_points);
+ memcpy((void*)output, (void*)intsToSwap, num_points * sizeof(uint16_t));
+
+}
+#endif
+
+#ifdef LV_HAVE_SSE2
+static inline void volk_16u_byteswappuppet_16u_a_sse2(uint16_t *output, uint16_t* intsToSwap, unsigned int num_points){
+
+ volk_16u_byteswap_a_sse2((uint16_t*)intsToSwap, num_points);
+ memcpy((void*)output, (void*)intsToSwap, num_points * sizeof(uint16_t));
+
+}
+#endif
+
+
+#endif
diff --git a/volk/kernels/volk/volk_32f_accumulator_s32f.h b/volk/kernels/volk/volk_32f_accumulator_s32f.h
index a67d10f9b5..e8995fb6c6 100644
--- a/volk/kernels/volk/volk_32f_accumulator_s32f.h
+++ b/volk/kernels/volk/volk_32f_accumulator_s32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_accumulator_s32f_a_H
#define INCLUDED_volk_32f_accumulator_s32f_a_H
diff --git a/volk/kernels/volk/volk_32f_acos_32f.h b/volk/kernels/volk/volk_32f_acos_32f.h
new file mode 100644
index 0000000000..1b2b734835
--- /dev/null
+++ b/volk/kernels/volk/volk_32f_acos_32f.h
@@ -0,0 +1,194 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include <inttypes.h>
+
+/* This is the number of terms of Taylor series to evaluate, increase this for more accuracy*/
+#define ACOS_TERMS 2
+
+#ifndef INCLUDED_volk_32f_acos_32f_a_H
+#define INCLUDED_volk_32f_acos_32f_a_H
+
+#ifdef LV_HAVE_SSE4_1
+#include <smmintrin.h>
+/*!
+ \brief Computes arccosine of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which arccosine is to be computed
+*/
+static inline void volk_32f_acos_32f_a_sse4_1(float* bVector, const float* aVector, unsigned int num_points){
+
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+
+ unsigned int number = 0;
+ unsigned int quarterPoints = num_points / 4;
+ int i, j;
+
+ __m128 aVal, d, pi, pio2, x, y, z, arccosine;
+ __m128 fzeroes, fones, ftwos, ffours, condition;
+
+ pi = _mm_set1_ps(3.14159265358979323846);
+ pio2 = _mm_set1_ps(3.14159265358979323846/2);
+ fzeroes = _mm_setzero_ps();
+ fones = _mm_set1_ps(1.0);
+ ftwos = _mm_set1_ps(2.0);
+ ffours = _mm_set1_ps(4.0);
+
+ for(;number < quarterPoints; number++){
+ aVal = _mm_load_ps(aPtr);
+ d = aVal;
+ aVal = _mm_div_ps(_mm_sqrt_ps(_mm_mul_ps(_mm_add_ps(fones, aVal), _mm_sub_ps(fones, aVal))), aVal);
+ z = aVal;
+ condition = _mm_cmplt_ps(z, fzeroes);
+ z = _mm_sub_ps(z, _mm_and_ps(_mm_mul_ps(z, ftwos), condition));
+ x = z;
+ condition = _mm_cmplt_ps(z, fones);
+ x = _mm_add_ps(x, _mm_and_ps(_mm_sub_ps(_mm_div_ps(fones, z), z), condition));
+
+ for(i = 0; i < 2; i++)
+ x = _mm_add_ps(x, _mm_sqrt_ps(_mm_add_ps(fones, _mm_mul_ps(x, x))));
+ x = _mm_div_ps(fones, x);
+ y = fzeroes;
+ for(j = ACOS_TERMS - 1; j >=0 ; j--)
+ y = _mm_add_ps(_mm_mul_ps(y, _mm_mul_ps(x, x)), _mm_set1_ps(pow(-1,j)/(2*j+1)));
+
+ y = _mm_mul_ps(y, _mm_mul_ps(x, ffours));
+ condition = _mm_cmpgt_ps(z, fones);
+
+ y = _mm_add_ps(y, _mm_and_ps(_mm_sub_ps(pio2, _mm_mul_ps(y, ftwos)), condition));
+ arccosine = y;
+ condition = _mm_cmplt_ps(aVal, fzeroes);
+ arccosine = _mm_sub_ps(arccosine, _mm_and_ps(_mm_mul_ps(arccosine, ftwos), condition));
+ condition = _mm_cmplt_ps(d, fzeroes);
+ arccosine = _mm_add_ps(arccosine, _mm_and_ps(pi, condition));
+
+ _mm_store_ps(bPtr, arccosine);
+ aPtr += 4;
+ bPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ *bPtr++ = acos(*aPtr++);
+ }
+}
+
+#endif /* LV_HAVE_SSE4_1 for aligned */
+
+#endif /* INCLUDED_volk_32f_acos_32f_a_H */
+
+
+#ifndef INCLUDED_volk_32f_acos_32f_u_H
+#define INCLUDED_volk_32f_acos_32f_u_H
+
+#ifdef LV_HAVE_SSE4_1
+#include <smmintrin.h>
+/*!
+ \brief Computes arccosine of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which arccosine is to be computed
+*/
+static inline void volk_32f_acos_32f_u_sse4_1(float* bVector, const float* aVector, unsigned int num_points){
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+
+ unsigned int number = 0;
+ unsigned int quarterPoints = num_points / 4;
+ int i, j;
+
+ __m128 aVal, d, pi, pio2, x, y, z, arccosine;
+ __m128 fzeroes, fones, ftwos, ffours, condition;
+
+ pi = _mm_set1_ps(3.14159265358979323846);
+ pio2 = _mm_set1_ps(3.14159265358979323846/2);
+ fzeroes = _mm_setzero_ps();
+ fones = _mm_set1_ps(1.0);
+ ftwos = _mm_set1_ps(2.0);
+ ffours = _mm_set1_ps(4.0);
+
+ for(;number < quarterPoints; number++){
+ aVal = _mm_loadu_ps(aPtr);
+ d = aVal;
+ aVal = _mm_div_ps(_mm_sqrt_ps(_mm_mul_ps(_mm_add_ps(fones, aVal), _mm_sub_ps(fones, aVal))), aVal);
+ z = aVal;
+ condition = _mm_cmplt_ps(z, fzeroes);
+ z = _mm_sub_ps(z, _mm_and_ps(_mm_mul_ps(z, ftwos), condition));
+ x = z;
+ condition = _mm_cmplt_ps(z, fones);
+ x = _mm_add_ps(x, _mm_and_ps(_mm_sub_ps(_mm_div_ps(fones, z), z), condition));
+
+ for(i = 0; i < 2; i++)
+ x = _mm_add_ps(x, _mm_sqrt_ps(_mm_add_ps(fones, _mm_mul_ps(x, x))));
+ x = _mm_div_ps(fones, x);
+ y = fzeroes;
+
+ for(j = ACOS_TERMS - 1; j >=0 ; j--)
+ y = _mm_add_ps(_mm_mul_ps(y, _mm_mul_ps(x, x)), _mm_set1_ps(pow(-1,j)/(2*j+1)));
+
+ y = _mm_mul_ps(y, _mm_mul_ps(x, ffours));
+ condition = _mm_cmpgt_ps(z, fones);
+
+ y = _mm_add_ps(y, _mm_and_ps(_mm_sub_ps(pio2, _mm_mul_ps(y, ftwos)), condition));
+ arccosine = y;
+ condition = _mm_cmplt_ps(aVal, fzeroes);
+ arccosine = _mm_sub_ps(arccosine, _mm_and_ps(_mm_mul_ps(arccosine, ftwos), condition));
+ condition = _mm_cmplt_ps(d, fzeroes);
+ arccosine = _mm_add_ps(arccosine, _mm_and_ps(pi, condition));
+
+ _mm_storeu_ps(bPtr, arccosine);
+ aPtr += 4;
+ bPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ *bPtr++ = acos(*aPtr++);
+ }
+}
+
+#endif /* LV_HAVE_SSE4_1 for aligned */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Computes arccosine of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which arccosine is to be computed
+*/
+static inline void volk_32f_acos_32f_generic(float* bVector, const float* aVector, unsigned int num_points){
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+ unsigned int number = 0;
+
+ for(number = 0; number < num_points; number++){
+ *bPtr++ = acos(*aPtr++);
+ }
+
+}
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_volk_32f_acos_32f_u_H */
diff --git a/volk/kernels/volk/volk_32f_asin_32f.h b/volk/kernels/volk/volk_32f_asin_32f.h
new file mode 100644
index 0000000000..7b80de7ee8
--- /dev/null
+++ b/volk/kernels/volk/volk_32f_asin_32f.h
@@ -0,0 +1,189 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include <inttypes.h>
+
+/* This is the number of terms of Taylor series to evaluate, increase this for more accuracy*/
+#define ASIN_TERMS 2
+
+#ifndef INCLUDED_volk_32f_asin_32f_a_H
+#define INCLUDED_volk_32f_asin_32f_a_H
+
+#ifdef LV_HAVE_SSE4_1
+#include <smmintrin.h>
+/*!
+ \brief Computes arcsine of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which arcsine is to be computed
+*/
+static inline void volk_32f_asin_32f_a_sse4_1(float* bVector, const float* aVector, unsigned int num_points){
+
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+
+ unsigned int number = 0;
+ unsigned int quarterPoints = num_points / 4;
+ int i, j;
+
+ __m128 aVal, pio2, x, y, z, arcsine;
+ __m128 fzeroes, fones, ftwos, ffours, condition;
+
+ pio2 = _mm_set1_ps(3.14159265358979323846/2);
+ fzeroes = _mm_setzero_ps();
+ fones = _mm_set1_ps(1.0);
+ ftwos = _mm_set1_ps(2.0);
+ ffours = _mm_set1_ps(4.0);
+
+ for(;number < quarterPoints; number++){
+ aVal = _mm_load_ps(aPtr);
+ aVal = _mm_div_ps(aVal, _mm_sqrt_ps(_mm_mul_ps(_mm_add_ps(fones, aVal), _mm_sub_ps(fones, aVal))));
+ z = aVal;
+ condition = _mm_cmplt_ps(z, fzeroes);
+ z = _mm_sub_ps(z, _mm_and_ps(_mm_mul_ps(z, ftwos), condition));
+ x = z;
+ condition = _mm_cmplt_ps(z, fones);
+ x = _mm_add_ps(x, _mm_and_ps(_mm_sub_ps(_mm_div_ps(fones, z), z), condition));
+
+ for(i = 0; i < 2; i++){
+ x = _mm_add_ps(x, _mm_sqrt_ps(_mm_add_ps(fones, _mm_mul_ps(x, x))));
+ }
+ x = _mm_div_ps(fones, x);
+ y = fzeroes;
+ for(j = ASIN_TERMS - 1; j >=0 ; j--){
+ y = _mm_add_ps(_mm_mul_ps(y, _mm_mul_ps(x, x)), _mm_set1_ps(pow(-1,j)/(2*j+1)));
+ }
+
+ y = _mm_mul_ps(y, _mm_mul_ps(x, ffours));
+ condition = _mm_cmpgt_ps(z, fones);
+
+ y = _mm_add_ps(y, _mm_and_ps(_mm_sub_ps(pio2, _mm_mul_ps(y, ftwos)), condition));
+ arcsine = y;
+ condition = _mm_cmplt_ps(aVal, fzeroes);
+ arcsine = _mm_sub_ps(arcsine, _mm_and_ps(_mm_mul_ps(arcsine, ftwos), condition));
+
+ _mm_store_ps(bPtr, arcsine);
+ aPtr += 4;
+ bPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ *bPtr++ = asin(*aPtr++);
+ }
+}
+
+#endif /* LV_HAVE_SSE4_1 for aligned */
+
+#endif /* INCLUDED_volk_32f_asin_32f_a_H */
+
+#ifndef INCLUDED_volk_32f_asin_32f_u_H
+#define INCLUDED_volk_32f_asin_32f_u_H
+
+#ifdef LV_HAVE_SSE4_1
+#include <smmintrin.h>
+/*!
+ \brief Computes arcsine of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which arcsine is to be computed
+*/
+static inline void volk_32f_asin_32f_u_sse4_1(float* bVector, const float* aVector, unsigned int num_points){
+
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+
+ unsigned int number = 0;
+ unsigned int quarterPoints = num_points / 4;
+ int i, j;
+
+ __m128 aVal, pio2, x, y, z, arcsine;
+ __m128 fzeroes, fones, ftwos, ffours, condition;
+
+ pio2 = _mm_set1_ps(3.14159265358979323846/2);
+ fzeroes = _mm_setzero_ps();
+ fones = _mm_set1_ps(1.0);
+ ftwos = _mm_set1_ps(2.0);
+ ffours = _mm_set1_ps(4.0);
+
+ for(;number < quarterPoints; number++){
+ aVal = _mm_loadu_ps(aPtr);
+ aVal = _mm_div_ps(aVal, _mm_sqrt_ps(_mm_mul_ps(_mm_add_ps(fones, aVal), _mm_sub_ps(fones, aVal))));
+ z = aVal;
+ condition = _mm_cmplt_ps(z, fzeroes);
+ z = _mm_sub_ps(z, _mm_and_ps(_mm_mul_ps(z, ftwos), condition));
+ x = z;
+ condition = _mm_cmplt_ps(z, fones);
+ x = _mm_add_ps(x, _mm_and_ps(_mm_sub_ps(_mm_div_ps(fones, z), z), condition));
+
+ for(i = 0; i < 2; i++){
+ x = _mm_add_ps(x, _mm_sqrt_ps(_mm_add_ps(fones, _mm_mul_ps(x, x))));
+ }
+ x = _mm_div_ps(fones, x);
+ y = fzeroes;
+ for(j = ASIN_TERMS - 1; j >=0 ; j--){
+ y = _mm_add_ps(_mm_mul_ps(y, _mm_mul_ps(x, x)), _mm_set1_ps(pow(-1,j)/(2*j+1)));
+ }
+
+ y = _mm_mul_ps(y, _mm_mul_ps(x, ffours));
+ condition = _mm_cmpgt_ps(z, fones);
+
+ y = _mm_add_ps(y, _mm_and_ps(_mm_sub_ps(pio2, _mm_mul_ps(y, ftwos)), condition));
+ arcsine = y;
+ condition = _mm_cmplt_ps(aVal, fzeroes);
+ arcsine = _mm_sub_ps(arcsine, _mm_and_ps(_mm_mul_ps(arcsine, ftwos), condition));
+
+ _mm_storeu_ps(bPtr, arcsine);
+ aPtr += 4;
+ bPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ *bPtr++ = asin(*aPtr++);
+ }
+}
+
+#endif /* LV_HAVE_SSE4_1 for unaligned */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Computes arcsine of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which arcsine is to be computed
+*/
+static inline void volk_32f_asin_32f_u_generic(float* bVector, const float* aVector, unsigned int num_points){
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+ unsigned int number = 0;
+
+ for(number = 0; number < num_points; number++){
+ *bPtr++ = asin(*aPtr++);
+ }
+
+}
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_volk_32f_asin_32f_u_H */
diff --git a/volk/kernels/volk/volk_32f_atan_32f.h b/volk/kernels/volk/volk_32f_atan_32f.h
new file mode 100644
index 0000000000..60742bb724
--- /dev/null
+++ b/volk/kernels/volk/volk_32f_atan_32f.h
@@ -0,0 +1,183 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include <inttypes.h>
+
+/* This is the number of terms of Taylor series to evaluate, increase this for more accuracy*/
+#define TERMS 2
+
+#ifndef INCLUDED_volk_32f_atan_32f_a_H
+#define INCLUDED_volk_32f_atan_32f_a_H
+
+#ifdef LV_HAVE_SSE4_1
+#include <smmintrin.h>
+/*!
+ \brief Computes arctangent of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which arctangent is to be computed
+*/
+static inline void volk_32f_atan_32f_a_sse4_1(float* bVector, const float* aVector, unsigned int num_points){
+
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+
+ unsigned int number = 0;
+ unsigned int quarterPoints = num_points / 4;
+ int i, j;
+
+ __m128 aVal, pio2, x, y, z, arctangent;
+ __m128 fzeroes, fones, ftwos, ffours, condition;
+
+ pio2 = _mm_set1_ps(3.14159265358979323846/2);
+ fzeroes = _mm_setzero_ps();
+ fones = _mm_set1_ps(1.0);
+ ftwos = _mm_set1_ps(2.0);
+ ffours = _mm_set1_ps(4.0);
+
+ for(;number < quarterPoints; number++){
+ aVal = _mm_load_ps(aPtr);
+ z = aVal;
+ condition = _mm_cmplt_ps(z, fzeroes);
+ z = _mm_sub_ps(z, _mm_and_ps(_mm_mul_ps(z, ftwos), condition));
+ x = z;
+ condition = _mm_cmplt_ps(z, fones);
+ x = _mm_add_ps(x, _mm_and_ps(_mm_sub_ps(_mm_div_ps(fones, z), z), condition));
+
+ for(i = 0; i < 2; i++){
+ x = _mm_add_ps(x, _mm_sqrt_ps(_mm_add_ps(fones, _mm_mul_ps(x, x))));
+ }
+ x = _mm_div_ps(fones, x);
+ y = fzeroes;
+ for(j = TERMS - 1; j >=0 ; j--){
+ y = _mm_add_ps(_mm_mul_ps(y, _mm_mul_ps(x, x)), _mm_set1_ps(pow(-1,j)/(2*j+1)));
+ }
+
+ y = _mm_mul_ps(y, _mm_mul_ps(x, ffours));
+ condition = _mm_cmpgt_ps(z, fones);
+
+ y = _mm_add_ps(y, _mm_and_ps(_mm_sub_ps(pio2, _mm_mul_ps(y, ftwos)), condition));
+ arctangent = y;
+ condition = _mm_cmplt_ps(aVal, fzeroes);
+ arctangent = _mm_sub_ps(arctangent, _mm_and_ps(_mm_mul_ps(arctangent, ftwos), condition));
+
+ _mm_store_ps(bPtr, arctangent);
+ aPtr += 4;
+ bPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ *bPtr++ = atan(*aPtr++);
+ }
+}
+
+#endif /* LV_HAVE_SSE4_1 for aligned */
+
+#endif /* INCLUDED_volk_32f_atan_32f_a_H */
+
+#ifndef INCLUDED_volk_32f_atan_32f_u_H
+#define INCLUDED_volk_32f_atan_32f_u_H
+
+#ifdef LV_HAVE_SSE4_1
+#include <smmintrin.h>
+/*!
+ \brief Computes arctangent of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which arctangent is to be computed
+*/
+static inline void volk_32f_atan_32f_u_sse4_1(float* bVector, const float* aVector, unsigned int num_points){
+
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+
+ unsigned int number = 0;
+ unsigned int quarterPoints = num_points / 4;
+ int i, j;
+
+ __m128 aVal, pio2, x, y, z, arctangent;
+ __m128 fzeroes, fones, ftwos, ffours, condition;
+
+ pio2 = _mm_set1_ps(3.14159265358979323846/2);
+ fzeroes = _mm_setzero_ps();
+ fones = _mm_set1_ps(1.0);
+ ftwos = _mm_set1_ps(2.0);
+ ffours = _mm_set1_ps(4.0);
+
+ for(;number < quarterPoints; number++){
+ aVal = _mm_loadu_ps(aPtr);
+ z = aVal;
+ condition = _mm_cmplt_ps(z, fzeroes);
+ z = _mm_sub_ps(z, _mm_and_ps(_mm_mul_ps(z, ftwos), condition));
+ x = z;
+ condition = _mm_cmplt_ps(z, fones);
+ x = _mm_add_ps(x, _mm_and_ps(_mm_sub_ps(_mm_div_ps(fones, z), z), condition));
+
+ for(i = 0; i < 2; i++) x = _mm_add_ps(x, _mm_sqrt_ps(_mm_add_ps(fones, _mm_mul_ps(x, x))));
+ x = _mm_div_ps(fones, x);
+ y = fzeroes;
+ for(j = TERMS - 1; j >= 0; j--) y = _mm_add_ps(_mm_mul_ps(y, _mm_mul_ps(x, x)), _mm_set1_ps(pow(-1,j)/(2*j+1)));
+
+ y = _mm_mul_ps(y, _mm_mul_ps(x, ffours));
+ condition = _mm_cmpgt_ps(z, fones);
+
+ y = _mm_add_ps(y, _mm_and_ps(_mm_sub_ps(pio2, _mm_mul_ps(y, ftwos)), condition));
+ arctangent = y;
+ condition = _mm_cmplt_ps(aVal, fzeroes);
+ arctangent = _mm_sub_ps(arctangent, _mm_and_ps(_mm_mul_ps(arctangent, ftwos), condition));
+
+ _mm_storeu_ps(bPtr, arctangent);
+ aPtr += 4;
+ bPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ *bPtr++ = atan(*aPtr++);
+ }
+}
+
+#endif /* LV_HAVE_SSE4_1 for unaligned */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Computes arctangent of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which arctangent is to be computed
+*/
+static inline void volk_32f_atan_32f_generic(float* bVector, const float* aVector, unsigned int num_points){
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+ unsigned int number = 0;
+
+ for(number = 0; number < num_points; number++){
+ *bPtr++ = atan(*aPtr++);
+ }
+
+}
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_volk_32f_atan_32f_u_H */
diff --git a/volk/kernels/volk/volk_32f_binary_slicer_32i.h b/volk/kernels/volk/volk_32f_binary_slicer_32i.h
index f47d20fd37..41f59148c2 100644
--- a/volk/kernels/volk/volk_32f_binary_slicer_32i.h
+++ b/volk/kernels/volk/volk_32f_binary_slicer_32i.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_binary_slicer_32i_H
#define INCLUDED_volk_32f_binary_slicer_32i_H
diff --git a/volk/kernels/volk/volk_32f_binary_slicer_8i.h b/volk/kernels/volk/volk_32f_binary_slicer_8i.h
index e24960cab7..ae4420b6e1 100644
--- a/volk/kernels/volk/volk_32f_binary_slicer_8i.h
+++ b/volk/kernels/volk/volk_32f_binary_slicer_8i.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_binary_slicer_8i_H
#define INCLUDED_volk_32f_binary_slicer_8i_H
@@ -184,4 +206,84 @@ volk_32f_binary_slicer_8i_u_sse2(int8_t* cVector, const float* aVector,
#endif /* LV_HAVE_SSE2 */
+#ifdef LV_HAVE_NEON
+#include <arm_neon.h>
+/*!
+ \brief Returns integer 1 if float input is greater than or equal to 0, 1 otherwise
+ \param cVector The char (int8_t) output (either 0 or 1)
+ \param aVector The float input
+ \param num_points The number of values in aVector and stored into cVector
+*/
+static inline void
+volk_32f_binary_slicer_8i_neon(int8_t* cVector, const float* aVector,
+ unsigned int num_points)
+{
+ int8_t* cPtr = cVector;
+ const float* aPtr = aVector;
+ unsigned int number = 0;
+ unsigned int n16points = num_points / 16;
+
+ float32x4x2_t input_val0, input_val1;
+ float32x4_t zero_val;
+ uint32x4x2_t res0_u32, res1_u32;
+ uint16x4x2_t res0_u16x4, res1_u16x4;
+ uint16x8x2_t res_u16x8;
+ uint8x8x2_t res_u8;
+ uint8x8_t one;
+
+ zero_val = vdupq_n_f32(0.0);
+ one = vdup_n_u8(0x01);
+
+ // TODO: this is a good candidate for asm because the vcombines
+ // can be eliminated simply by picking dst registers that are
+ // adjacent.
+ for(number = 0; number < n16points; number++) {
+ input_val0 = vld2q_f32(aPtr);
+ input_val1 = vld2q_f32(aPtr+8);
+
+ // test against 0; return uint32
+ res0_u32.val[0] = vcgeq_f32(input_val0.val[0], zero_val);
+ res0_u32.val[1] = vcgeq_f32(input_val0.val[1], zero_val);
+ res1_u32.val[0] = vcgeq_f32(input_val1.val[0], zero_val);
+ res1_u32.val[1] = vcgeq_f32(input_val1.val[1], zero_val);
+
+ // narrow uint32 -> uint16 followed by combine to 8-element vectors
+ res0_u16x4.val[0] = vmovn_u32(res0_u32.val[0]);
+ res0_u16x4.val[1] = vmovn_u32(res0_u32.val[1]);
+ res1_u16x4.val[0] = vmovn_u32(res1_u32.val[0]);
+ res1_u16x4.val[1] = vmovn_u32(res1_u32.val[1]);
+
+ res_u16x8.val[0] = vcombine_u16(res0_u16x4.val[0], res1_u16x4.val[0]);
+ res_u16x8.val[1] = vcombine_u16(res0_u16x4.val[1], res1_u16x4.val[1]);
+
+ // narrow uint16x8 -> uint8x8
+ res_u8.val[0] = vmovn_u16(res_u16x8.val[0]);
+ res_u8.val[1] = vmovn_u16(res_u16x8.val[1]);
+ // we *could* load twice as much data and do another vcombine here
+ // to get a uint8x16x2 vector, still only do 2 vandqs and a single store
+ // but that turns out to be ~16% slower than this version on zc702
+ // it's possible register contention in GCC scheduler slows it down
+ // and a hand-written asm with quad-word u8 registers is much faster.
+
+ res_u8.val[0] = vand_u8(one, res_u8.val[0]);
+ res_u8.val[1] = vand_u8(one, res_u8.val[1]);
+
+ vst2_u8((unsigned char*)cPtr, res_u8);
+ cPtr += 16;
+ aPtr += 16;
+
+ }
+
+ for(number = n16points * 16; number < num_points; number++) {
+ if(*aPtr++ >= 0) {
+ *cPtr++ = 1;
+ }
+ else {
+ *cPtr++ = 0;
+ }
+ }
+}
+#endif /* LV_HAVE_NEON */
+
+
#endif /* INCLUDED_volk_32f_binary_slicer_8i_H */
diff --git a/volk/kernels/volk/volk_32f_convert_64f.h b/volk/kernels/volk/volk_32f_convert_64f.h
index 2f036955dd..96a411c800 100644
--- a/volk/kernels/volk/volk_32f_convert_64f.h
+++ b/volk/kernels/volk/volk_32f_convert_64f.h
@@ -1,9 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_convert_64f_u_H
#define INCLUDED_volk_32f_convert_64f_u_H
#include <inttypes.h>
#include <stdio.h>
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+ /*!
+ \brief Converts the float values into double values
+ \param dVector The converted double vector values
+ \param fVector The float vector values to be converted
+ \param num_points The number of points in the two vectors to be converted
+ */
+
+static inline void volk_32f_convert_64f_u_avx(double* outputVector, const float* inputVector, unsigned int num_points){
+ unsigned int number = 0;
+
+ const unsigned int quarterPoints = num_points / 4;
+
+ const float* inputVectorPtr = (const float*)inputVector;
+ double* outputVectorPtr = outputVector;
+ __m256d ret;
+ __m128 inputVal;
+
+ for(;number < quarterPoints; number++){
+ inputVal = _mm_loadu_ps(inputVectorPtr); inputVectorPtr += 4;
+
+ ret = _mm256_cvtps_pd(inputVal);
+ _mm256_storeu_pd(outputVectorPtr, ret);
+
+ outputVectorPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(; number < num_points; number++){
+ outputVector[number] = (double)(inputVector[number]);
+ }
+}
+
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_SSE2
#include <emmintrin.h>
/*!
@@ -68,12 +126,48 @@ static inline void volk_32f_convert_64f_generic(double* outputVector, const floa
#endif /* INCLUDED_volk_32f_convert_64f_u_H */
+
+
#ifndef INCLUDED_volk_32f_convert_64f_a_H
#define INCLUDED_volk_32f_convert_64f_a_H
#include <inttypes.h>
#include <stdio.h>
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+ /*!
+ \brief Converts the float values into double values
+ \param dVector The converted double vector values
+ \param fVector The float vector values to be converted
+ \param num_points The number of points in the two vectors to be converted
+ */
+static inline void volk_32f_convert_64f_a_avx(double* outputVector, const float* inputVector, unsigned int num_points){
+ unsigned int number = 0;
+
+ const unsigned int quarterPoints = num_points / 4;
+
+ const float* inputVectorPtr = (const float*)inputVector;
+ double* outputVectorPtr = outputVector;
+ __m256d ret;
+ __m128 inputVal;
+
+ for(;number < quarterPoints; number++){
+ inputVal = _mm_load_ps(inputVectorPtr); inputVectorPtr += 4;
+
+ ret = _mm256_cvtps_pd(inputVal);
+ _mm256_store_pd(outputVectorPtr, ret);
+
+ outputVectorPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(; number < num_points; number++){
+ outputVector[number] = (double)(inputVector[number]);
+ }
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_SSE2
#include <emmintrin.h>
/*!
diff --git a/volk/kernels/volk/volk_32f_cos_32f.h b/volk/kernels/volk/volk_32f_cos_32f.h
new file mode 100644
index 0000000000..49c56580bf
--- /dev/null
+++ b/volk/kernels/volk/volk_32f_cos_32f.h
@@ -0,0 +1,211 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include <inttypes.h>
+
+#ifndef INCLUDED_volk_32f_cos_32f_a_H
+#define INCLUDED_volk_32f_cos_32f_a_H
+
+#ifdef LV_HAVE_SSE4_1
+#include <smmintrin.h>
+/*!
+ \brief Computes cosine of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which cosine is to be computed
+*/
+static inline void volk_32f_cos_32f_a_sse4_1(float* bVector, const float* aVector, unsigned int num_points){
+
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+
+ unsigned int number = 0;
+ unsigned int quarterPoints = num_points / 4;
+ unsigned int i = 0;
+
+ __m128 aVal, s, m4pi, pio4A, pio4B, cp1, cp2, cp3, cp4, cp5, ffours, ftwos, fones, fzeroes;
+ __m128 sine, cosine, condition1, condition3;
+ __m128i q, r, ones, twos, fours;
+
+ m4pi = _mm_set1_ps(1.273239545);
+ pio4A = _mm_set1_ps(0.78515625);
+ pio4B = _mm_set1_ps(0.241876e-3);
+ ffours = _mm_set1_ps(4.0);
+ ftwos = _mm_set1_ps(2.0);
+ fones = _mm_set1_ps(1.0);
+ fzeroes = _mm_setzero_ps();
+ ones = _mm_set1_epi32(1);
+ twos = _mm_set1_epi32(2);
+ fours = _mm_set1_epi32(4);
+
+ cp1 = _mm_set1_ps(1.0);
+ cp2 = _mm_set1_ps(0.83333333e-1);
+ cp3 = _mm_set1_ps(0.2777778e-2);
+ cp4 = _mm_set1_ps(0.49603e-4);
+ cp5 = _mm_set1_ps(0.551e-6);
+
+ for(;number < quarterPoints; number++){
+
+ aVal = _mm_load_ps(aPtr);
+ s = _mm_sub_ps(aVal, _mm_and_ps(_mm_mul_ps(aVal, ftwos), _mm_cmplt_ps(aVal, fzeroes)));
+ q = _mm_cvtps_epi32(_mm_mul_ps(s, m4pi));
+ r = _mm_add_epi32(q, _mm_and_si128(q, ones));
+
+ s = _mm_sub_ps(s, _mm_mul_ps(_mm_cvtepi32_ps(r), pio4A));
+ s = _mm_sub_ps(s, _mm_mul_ps(_mm_cvtepi32_ps(r), pio4B));
+
+ s = _mm_div_ps(s, _mm_set1_ps(8.0)); // The constant is 2^N, for 3 times argument reduction
+ s = _mm_mul_ps(s, s);
+ // Evaluate Taylor series
+ s = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(_mm_sub_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(_mm_sub_ps(_mm_mul_ps(s, cp5), cp4), s), cp3), s), cp2), s), cp1), s);
+
+ for(i = 0; i < 3; i++) s = _mm_mul_ps(s, _mm_sub_ps(ffours, s));
+ s = _mm_div_ps(s, ftwos);
+
+ sine = _mm_sqrt_ps(_mm_mul_ps(_mm_sub_ps(ftwos, s), s));
+ cosine = _mm_sub_ps(fones, s);
+
+ condition1 = _mm_cmpneq_ps(_mm_cvtepi32_ps(_mm_and_si128(_mm_add_epi32(q, ones), twos)), fzeroes);
+
+ condition3 = _mm_cmpneq_ps(_mm_cvtepi32_ps(_mm_and_si128(_mm_add_epi32(q, twos), fours)), fzeroes);
+
+ cosine = _mm_add_ps(cosine, _mm_and_ps(_mm_sub_ps(sine, cosine), condition1));
+ cosine = _mm_sub_ps(cosine, _mm_and_ps(_mm_mul_ps(cosine, _mm_set1_ps(2.0f)), condition3));
+ _mm_store_ps(bPtr, cosine);
+ aPtr += 4;
+ bPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ *bPtr++ = cos(*aPtr++);
+ }
+}
+
+#endif /* LV_HAVE_SSE4_1 for aligned */
+
+#endif /* INCLUDED_volk_32f_cos_32f_a_H */
+
+#ifndef INCLUDED_volk_32f_cos_32f_u_H
+#define INCLUDED_volk_32f_cos_32f_u_H
+
+#ifdef LV_HAVE_SSE4_1
+#include <smmintrin.h>
+/*!
+ \brief Computes cosine of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which cosine is to be computed
+*/
+static inline void volk_32f_cos_32f_u_sse4_1(float* bVector, const float* aVector, unsigned int num_points){
+
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+
+ unsigned int number = 0;
+ unsigned int quarterPoints = num_points / 4;
+ unsigned int i = 0;
+
+ __m128 aVal, s, m4pi, pio4A, pio4B, cp1, cp2, cp3, cp4, cp5, ffours, ftwos, fones, fzeroes;
+ __m128 sine, cosine, condition1, condition3;
+ __m128i q, r, ones, twos, fours;
+
+ m4pi = _mm_set1_ps(1.273239545);
+ pio4A = _mm_set1_ps(0.78515625);
+ pio4B = _mm_set1_ps(0.241876e-3);
+ ffours = _mm_set1_ps(4.0);
+ ftwos = _mm_set1_ps(2.0);
+ fones = _mm_set1_ps(1.0);
+ fzeroes = _mm_setzero_ps();
+ ones = _mm_set1_epi32(1);
+ twos = _mm_set1_epi32(2);
+ fours = _mm_set1_epi32(4);
+
+ cp1 = _mm_set1_ps(1.0);
+ cp2 = _mm_set1_ps(0.83333333e-1);
+ cp3 = _mm_set1_ps(0.2777778e-2);
+ cp4 = _mm_set1_ps(0.49603e-4);
+ cp5 = _mm_set1_ps(0.551e-6);
+
+ for(;number < quarterPoints; number++){
+ aVal = _mm_loadu_ps(aPtr);
+ s = _mm_sub_ps(aVal, _mm_and_ps(_mm_mul_ps(aVal, ftwos), _mm_cmplt_ps(aVal, fzeroes)));
+ q = _mm_cvtps_epi32(_mm_mul_ps(s, m4pi));
+ r = _mm_add_epi32(q, _mm_and_si128(q, ones));
+
+ s = _mm_sub_ps(s, _mm_mul_ps(_mm_cvtepi32_ps(r), pio4A));
+ s = _mm_sub_ps(s, _mm_mul_ps(_mm_cvtepi32_ps(r), pio4B));
+
+ s = _mm_div_ps(s, _mm_set1_ps(8.0)); // The constant is 2^N, for 3 times argument reduction
+ s = _mm_mul_ps(s, s);
+ // Evaluate Taylor series
+ s = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(_mm_sub_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(_mm_sub_ps(_mm_mul_ps(s, cp5), cp4), s), cp3), s), cp2), s), cp1), s);
+
+ for(i = 0; i < 3; i++){
+ s = _mm_mul_ps(s, _mm_sub_ps(ffours, s));
+ }
+ s = _mm_div_ps(s, ftwos);
+
+ sine = _mm_sqrt_ps(_mm_mul_ps(_mm_sub_ps(ftwos, s), s));
+ cosine = _mm_sub_ps(fones, s);
+
+ condition1 = _mm_cmpneq_ps(_mm_cvtepi32_ps(_mm_and_si128(_mm_add_epi32(q, ones), twos)), fzeroes);
+
+ condition3 = _mm_cmpneq_ps(_mm_cvtepi32_ps(_mm_and_si128(_mm_add_epi32(q, twos), fours)), fzeroes);
+
+ cosine = _mm_add_ps(cosine, _mm_and_ps(_mm_sub_ps(sine, cosine), condition1));
+ cosine = _mm_sub_ps(cosine, _mm_and_ps(_mm_mul_ps(cosine, _mm_set1_ps(2.0f)), condition3));
+ _mm_storeu_ps(bPtr, cosine);
+ aPtr += 4;
+ bPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ *bPtr++ = cos(*aPtr++);
+ }
+}
+
+#endif /* LV_HAVE_SSE4_1 for unaligned */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Computes cosine of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which cosine is to be computed
+*/
+static inline void volk_32f_cos_32f_generic(float* bVector, const float* aVector, unsigned int num_points){
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+ unsigned int number = 0;
+
+ for(; number < num_points; number++){
+ *bPtr++ = cos(*aPtr++);
+ }
+
+}
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_volk_32f_cos_32f_u_H */
diff --git a/volk/kernels/volk/volk_32f_expfast_32f.h b/volk/kernels/volk/volk_32f_expfast_32f.h
new file mode 100644
index 0000000000..b64e45c86e
--- /dev/null
+++ b/volk/kernels/volk/volk_32f_expfast_32f.h
@@ -0,0 +1,216 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include <inttypes.h>
+
+#define Mln2 0.6931471805f
+#define A 8388608.0f
+#define B 1065353216.0f
+#define C 60801.0f
+
+
+#ifndef INCLUDED_volk_32f_expfast_32f_a_H
+#define INCLUDED_volk_32f_expfast_32f_a_H
+
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+/*!
+ \brief Computes fast exp (max 7% error) of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which exp is to be computed
+*/
+static inline void volk_32f_expfast_32f_a_avx(float* bVector, const float* aVector, unsigned int num_points){
+
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+
+ unsigned int number = 0;
+ const unsigned int eighthPoints = num_points / 8;
+
+ __m256 aVal, bVal, a, b;
+ __m256i exp;
+ a = _mm256_set1_ps(A/Mln2);
+ b = _mm256_set1_ps(B-C);
+
+ for(;number < eighthPoints; number++){
+ aVal = _mm256_load_ps(aPtr);
+ exp = _mm256_cvtps_epi32(_mm256_add_ps(_mm256_mul_ps(a,aVal), b));
+ bVal = _mm256_castsi256_ps(exp);
+
+ _mm256_store_ps(bPtr, bVal);
+ aPtr += 8;
+ bPtr += 8;
+ }
+
+ number = eighthPoints * 8;
+ for(;number < num_points; number++){
+ *bPtr++ = expf(*aPtr++);
+ }
+}
+
+#endif /* LV_HAVE_AVX for aligned */
+
+#ifdef LV_HAVE_SSE4_1
+#include <smmintrin.h>
+/*!
+ \brief Computes fast exp (max 7% error) of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which exp is to be computed
+*/
+static inline void volk_32f_expfast_32f_a_sse4_1(float* bVector, const float* aVector, unsigned int num_points){
+
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ __m128 aVal, bVal, a, b;
+ __m128i exp;
+ a = _mm_set1_ps(A/Mln2);
+ b = _mm_set1_ps(B-C);
+
+ for(;number < quarterPoints; number++){
+ aVal = _mm_load_ps(aPtr);
+ exp = _mm_cvtps_epi32(_mm_add_ps(_mm_mul_ps(a,aVal), b));
+ bVal = _mm_castsi128_ps(exp);
+
+ _mm_store_ps(bPtr, bVal);
+ aPtr += 4;
+ bPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ *bPtr++ = expf(*aPtr++);
+ }
+}
+
+#endif /* LV_HAVE_SSE4_1 for aligned */
+
+#endif /* INCLUDED_volk_32f_expfast_32f_a_H */
+
+#ifndef INCLUDED_volk_32f_expfast_32f_u_H
+#define INCLUDED_volk_32f_expfast_32f_u_H
+
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+/*!
+ \brief Computes fast exp (max 7% error) of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which exp is to be computed
+*/
+static inline void volk_32f_expfast_32f_u_avx(float* bVector, const float* aVector, unsigned int num_points){
+
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+
+ unsigned int number = 0;
+ const unsigned int eighthPoints = num_points / 8;
+
+ __m256 aVal, bVal, a, b;
+ __m256i exp;
+ a = _mm256_set1_ps(A/Mln2);
+ b = _mm256_set1_ps(B-C);
+
+ for(;number < eighthPoints; number++){
+ aVal = _mm256_loadu_ps(aPtr);
+ exp = _mm256_cvtps_epi32(_mm256_add_ps(_mm256_mul_ps(a,aVal), b));
+ bVal = _mm256_castsi256_ps(exp);
+
+ _mm256_storeu_ps(bPtr, bVal);
+ aPtr += 8;
+ bPtr += 8;
+ }
+
+ number = eighthPoints * 8;
+ for(;number < num_points; number++){
+ *bPtr++ = expf(*aPtr++);
+ }
+}
+
+#endif /* LV_HAVE_AVX for aligned */
+
+#ifdef LV_HAVE_SSE4_1
+#include <smmintrin.h>
+/*!
+ \brief Computes fast exp (max 7% error) of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which log is to be computed
+*/
+static inline void volk_32f_expfast_32f_u_sse4_1(float* bVector, const float* aVector, unsigned int num_points){
+
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ __m128 aVal, bVal, a, b;
+ __m128i exp;
+ a = _mm_set1_ps(A/Mln2);
+ b = _mm_set1_ps(B-C);
+
+ for(;number < quarterPoints; number++){
+ aVal = _mm_loadu_ps(aPtr);
+ exp = _mm_cvtps_epi32(_mm_add_ps(_mm_mul_ps(a,aVal), b));
+ bVal = _mm_castsi128_ps(exp);
+
+ _mm_storeu_ps(bPtr, bVal);
+ aPtr += 4;
+ bPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ *bPtr++ = expf(*aPtr++);
+ }
+}
+
+#endif /* LV_HAVE_SSE4_1 for unaligned */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Computes fast exp (max 7% error) of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which log is to be computed
+*/
+static inline void volk_32f_expfast_32f_generic(float* bVector, const float* aVector, unsigned int num_points){
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+ unsigned int number = 0;
+
+ for(number = 0; number < num_points; number++){
+ *bPtr++ = expf(*aPtr++);
+ }
+
+}
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_volk_32f_expfast_32f_u_H */
diff --git a/volk/kernels/volk/volk_32f_index_max_16u.h b/volk/kernels/volk/volk_32f_index_max_16u.h
index dd1aed2459..a5482a6a61 100644
--- a/volk/kernels/volk/volk_32f_index_max_16u.h
+++ b/volk/kernels/volk/volk_32f_index_max_16u.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_index_max_16u_a_H
#define INCLUDED_volk_32f_index_max_16u_a_H
diff --git a/volk/kernels/volk/volk_32f_invsqrt_32f.h b/volk/kernels/volk/volk_32f_invsqrt_32f.h
index 8ea12a73c4..21ed125053 100644
--- a/volk/kernels/volk/volk_32f_invsqrt_32f.h
+++ b/volk/kernels/volk/volk_32f_invsqrt_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_invsqrt_32f_a_H
#define INCLUDED_volk_32f_invsqrt_32f_a_H
@@ -113,7 +135,7 @@ static inline void volk_32f_invsqrt_32f_neon(float* cVector, const float* aVecto
aPtr += 4;
cPtr += 4;
}
-
+
for(number=quarter_points * 4;number < num_points; number++)
*cPtr++ = Q_rsqrt(*aPtr++);
diff --git a/volk/kernels/volk/volk_32f_log2_32f.h b/volk/kernels/volk/volk_32f_log2_32f.h
new file mode 100644
index 0000000000..892eeb1685
--- /dev/null
+++ b/volk/kernels/volk/volk_32f_log2_32f.h
@@ -0,0 +1,332 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along 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 kernel was adapted from Jose Fonseca's Fast SSE2 log implementation
+ * http://jrfonseca.blogspot.in/2008/09/fast-sse2-pow-tables-or-polynomials.htm
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ * This is the MIT License (MIT)
+
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <math.h>
+
+#define POLY0(x, c0) _mm_set1_ps(c0)
+#define POLY1(x, c0, c1) _mm_add_ps(_mm_mul_ps(POLY0(x, c1), x), _mm_set1_ps(c0))
+#define POLY2(x, c0, c1, c2) _mm_add_ps(_mm_mul_ps(POLY1(x, c1, c2), x), _mm_set1_ps(c0))
+#define POLY3(x, c0, c1, c2, c3) _mm_add_ps(_mm_mul_ps(POLY2(x, c1, c2, c3), x), _mm_set1_ps(c0))
+#define POLY4(x, c0, c1, c2, c3, c4) _mm_add_ps(_mm_mul_ps(POLY3(x, c1, c2, c3, c4), x), _mm_set1_ps(c0))
+#define POLY5(x, c0, c1, c2, c3, c4, c5) _mm_add_ps(_mm_mul_ps(POLY4(x, c1, c2, c3, c4, c5), x), _mm_set1_ps(c0))
+
+#define LOG_POLY_DEGREE 6
+
+
+#ifndef INCLUDED_volk_32f_log2_32f_a_H
+#define INCLUDED_volk_32f_log2_32f_a_H
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Computes base 2 log of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which log is to be computed
+*/
+static inline void volk_32f_log2_32f_generic(float* bVector, const float* aVector, unsigned int num_points){
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+ unsigned int number = 0;
+
+ for(number = 0; number < num_points; number++){
+ *bPtr++ = log2(*aPtr++);
+ }
+
+}
+#endif /* LV_HAVE_GENERIC */
+
+
+#ifdef LV_HAVE_SSE4_1
+#include <smmintrin.h>
+/*!
+ \brief Computes base 2 log of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which log is to be computed
+*/
+static inline void volk_32f_log2_32f_a_sse4_1(float* bVector, const float* aVector, unsigned int num_points){
+
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ __m128 aVal, bVal, mantissa, frac, leadingOne;
+ __m128i bias, exp;
+
+ for(;number < quarterPoints; number++){
+
+ aVal = _mm_load_ps(aPtr);
+ bias = _mm_set1_epi32(127);
+ leadingOne = _mm_set1_ps(1.0f);
+ exp = _mm_sub_epi32(_mm_srli_epi32(_mm_and_si128(_mm_castps_si128(aVal), _mm_set1_epi32(0x7f800000)), 23), bias);
+ bVal = _mm_cvtepi32_ps(exp);
+
+ // Now to extract mantissa
+ frac = _mm_or_ps(leadingOne, _mm_and_ps(aVal, _mm_castsi128_ps(_mm_set1_epi32(0x7fffff))));
+
+ #if LOG_POLY_DEGREE == 6
+ mantissa = POLY5( frac, 3.1157899f, -3.3241990f, 2.5988452f, -1.2315303f, 3.1821337e-1f, -3.4436006e-2f);
+ #elif LOG_POLY_DEGREE == 5
+ mantissa = POLY4( frac, 2.8882704548164776201f, -2.52074962577807006663f, 1.48116647521213171641f, -0.465725644288844778798f, 0.0596515482674574969533f);
+ #elif LOG_POLY_DEGREE == 4
+ mantissa = POLY3( frac, 2.61761038894603480148f, -1.75647175389045657003f, 0.688243882994381274313f, -0.107254423828329604454f);
+ #elif LOG_POLY_DEGREE == 3
+ mantissa = POLY2( frac, 2.28330284476918490682f, -1.04913055217340124191f, 0.204446009836232697516f);
+ #else
+ #error
+ #endif
+
+ bVal = _mm_add_ps(bVal, _mm_mul_ps(mantissa, _mm_sub_ps(frac, leadingOne)));
+ _mm_store_ps(bPtr, bVal);
+
+
+ aPtr += 4;
+ bPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ *bPtr++ = log2(*aPtr++);
+ }
+}
+
+#endif /* LV_HAVE_SSE4_1 for aligned */
+
+
+#ifdef LV_HAVE_NEON
+#include <arm_neon.h>
+
+/* these macros allow us to embed logs in other kernels */
+#define VLOG2Q_NEON_PREAMBLE() \
+ int32x4_t one = vdupq_n_s32(0x000800000); \
+ /* minimax polynomial */ \
+ float32x4_t p0 = vdupq_n_f32(-3.0400402727048585); \
+ float32x4_t p1 = vdupq_n_f32(6.1129631282966113); \
+ float32x4_t p2 = vdupq_n_f32(-5.3419892024633207); \
+ float32x4_t p3 = vdupq_n_f32(3.2865287703753912); \
+ float32x4_t p4 = vdupq_n_f32(-1.2669182593441635); \
+ float32x4_t p5 = vdupq_n_f32(0.2751487703421256); \
+ float32x4_t p6 = vdupq_n_f32(-0.0256910888150985); \
+ int32x4_t exp_mask = vdupq_n_s32(0x7f800000); \
+ int32x4_t sig_mask = vdupq_n_s32(0x007fffff); \
+ int32x4_t exp_bias = vdupq_n_s32(127);
+
+
+#define VLOG2Q_NEON_F32(log2_approx, aval) \
+ int32x4_t exponent_i = vandq_s32(aval, exp_mask); \
+ int32x4_t significand_i = vandq_s32(aval, sig_mask); \
+ exponent_i = vshrq_n_s32(exponent_i, 23); \
+ \
+ /* extract the exponent and significand \
+ we can treat this as fixed point to save ~9% on the \
+ conversion + float add */ \
+ significand_i = vorrq_s32(one, significand_i); \
+ float32x4_t significand_f = vcvtq_n_f32_s32(significand_i,23); \
+ /* debias the exponent and convert to float */ \
+ exponent_i = vsubq_s32(exponent_i, exp_bias); \
+ float32x4_t exponent_f = vcvtq_f32_s32(exponent_i); \
+ \
+ /* put the significand through a polynomial fit of log2(x) [1,2]\
+ add the result to the exponent */ \
+ log2_approx = vaddq_f32(exponent_f, p0); /* p0 */ \
+ float32x4_t tmp1 = vmulq_f32(significand_f, p1); /* p1 * x */ \
+ log2_approx = vaddq_f32(log2_approx, tmp1); \
+ float32x4_t sig_2 = vmulq_f32(significand_f, significand_f); /* x^2 */ \
+ tmp1 = vmulq_f32(sig_2, p2); /* p2 * x^2 */ \
+ log2_approx = vaddq_f32(log2_approx, tmp1); \
+ \
+ float32x4_t sig_3 = vmulq_f32(sig_2, significand_f); /* x^3 */ \
+ tmp1 = vmulq_f32(sig_3, p3); /* p3 * x^3 */ \
+ log2_approx = vaddq_f32(log2_approx, tmp1); \
+ float32x4_t sig_4 = vmulq_f32(sig_2, sig_2); /* x^4 */ \
+ tmp1 = vmulq_f32(sig_4, p4); /* p4 * x^4 */ \
+ log2_approx = vaddq_f32(log2_approx, tmp1); \
+ float32x4_t sig_5 = vmulq_f32(sig_3, sig_2); /* x^5 */ \
+ tmp1 = vmulq_f32(sig_5, p5); /* p5 * x^5 */ \
+ log2_approx = vaddq_f32(log2_approx, tmp1); \
+ float32x4_t sig_6 = vmulq_f32(sig_3, sig_3); /* x^6 */ \
+ tmp1 = vmulq_f32(sig_6, p6); /* p6 * x^6 */ \
+ log2_approx = vaddq_f32(log2_approx, tmp1);
+
+/*!
+ \brief Computes base 2 log of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which log is to be computed
+*/
+static inline void volk_32f_log2_32f_neon(float* bVector, const float* aVector, unsigned int num_points){
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+ unsigned int number;
+ const unsigned int quarterPoints = num_points / 4;
+
+ int32x4_t aval;
+ float32x4_t log2_approx;
+
+ VLOG2Q_NEON_PREAMBLE()
+ // lms
+ //p0 = vdupq_n_f32(-1.649132280361871);
+ //p1 = vdupq_n_f32(1.995047138579499);
+ //p2 = vdupq_n_f32(-0.336914839219728);
+
+ // keep in mind a single precision float is represented as
+ // (-1)^sign * 2^exp * 1.significand, so the log2 is
+ // log2(2^exp * sig) = exponent + log2(1 + significand/(1<<23)
+ for(number = 0; number < quarterPoints; ++number){
+ // load float in to an int register without conversion
+ aval = vld1q_s32((int*)aPtr);
+
+ VLOG2Q_NEON_F32(log2_approx, aval)
+
+ vst1q_f32(bPtr, log2_approx);
+
+ aPtr += 4;
+ bPtr += 4;
+ }
+
+ for(number = quarterPoints * 4; number < num_points; number++){
+ *bPtr++ = log2(*aPtr++);
+ }
+}
+
+#endif /* LV_HAVE_NEON */
+
+
+#endif /* INCLUDED_volk_32f_log2_32f_a_H */
+
+#ifndef INCLUDED_volk_32f_log2_32f_u_H
+#define INCLUDED_volk_32f_log2_32f_u_H
+
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Computes base 2 log of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which log is to be computed
+*/
+static inline void volk_32f_log2_32f_u_generic(float* bVector, const float* aVector, unsigned int num_points){
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+ unsigned int number = 0;
+
+ for(number = 0; number < num_points; number++){
+ *bPtr++ = log2(*aPtr++);
+ }
+
+}
+#endif /* LV_HAVE_GENERIC */
+
+
+#ifdef LV_HAVE_SSE4_1
+#include <smmintrin.h>
+/*!
+ \brief Computes base 2 log of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which log is to be computed
+*/
+static inline void volk_32f_log2_32f_u_sse4_1(float* bVector, const float* aVector, unsigned int num_points){
+
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ __m128 aVal, bVal, mantissa, frac, leadingOne;
+ __m128i bias, exp;
+
+ for(;number < quarterPoints; number++){
+
+ aVal = _mm_loadu_ps(aPtr);
+ bias = _mm_set1_epi32(127);
+ leadingOne = _mm_set1_ps(1.0f);
+ exp = _mm_sub_epi32(_mm_srli_epi32(_mm_and_si128(_mm_castps_si128(aVal), _mm_set1_epi32(0x7f800000)), 23), bias);
+ bVal = _mm_cvtepi32_ps(exp);
+
+ // Now to extract mantissa
+ frac = _mm_or_ps(leadingOne, _mm_and_ps(aVal, _mm_castsi128_ps(_mm_set1_epi32(0x7fffff))));
+
+ #if LOG_POLY_DEGREE == 6
+ mantissa = POLY5( frac, 3.1157899f, -3.3241990f, 2.5988452f, -1.2315303f, 3.1821337e-1f, -3.4436006e-2f);
+ #elif LOG_POLY_DEGREE == 5
+ mantissa = POLY4( frac, 2.8882704548164776201f, -2.52074962577807006663f, 1.48116647521213171641f, -0.465725644288844778798f, 0.0596515482674574969533f);
+ #elif LOG_POLY_DEGREE == 4
+ mantissa = POLY3( frac, 2.61761038894603480148f, -1.75647175389045657003f, 0.688243882994381274313f, -0.107254423828329604454f);
+ #elif LOG_POLY_DEGREE == 3
+ mantissa = POLY2( frac, 2.28330284476918490682f, -1.04913055217340124191f, 0.204446009836232697516f);
+ #else
+ #error
+ #endif
+
+ bVal = _mm_add_ps(bVal, _mm_mul_ps(mantissa, _mm_sub_ps(frac, leadingOne)));
+ _mm_storeu_ps(bPtr, bVal);
+
+
+ aPtr += 4;
+ bPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ *bPtr++ = log2(*aPtr++);
+ }
+}
+
+#endif /* LV_HAVE_SSE4_1 for unaligned */
+
+#endif /* INCLUDED_volk_32f_log2_32f_u_H */
diff --git a/volk/kernels/volk/volk_32f_s32f_32f_fm_detect_32f.h b/volk/kernels/volk/volk_32f_s32f_32f_fm_detect_32f.h
index 71881c2d5f..f03d80bdd6 100644
--- a/volk/kernels/volk/volk_32f_s32f_32f_fm_detect_32f.h
+++ b/volk/kernels/volk/volk_32f_s32f_32f_fm_detect_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_s32f_32f_fm_detect_32f_a_H
#define INCLUDED_volk_32f_s32f_32f_fm_detect_32f_a_H
diff --git a/volk/kernels/volk/volk_32f_s32f_calc_spectral_noise_floor_32f.h b/volk/kernels/volk/volk_32f_s32f_calc_spectral_noise_floor_32f.h
index bf05a882d5..9b9f5d3afb 100644
--- a/volk/kernels/volk/volk_32f_s32f_calc_spectral_noise_floor_32f.h
+++ b/volk/kernels/volk/volk_32f_s32f_calc_spectral_noise_floor_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_s32f_calc_spectral_noise_floor_32f_a_H
#define INCLUDED_volk_32f_s32f_calc_spectral_noise_floor_32f_a_H
diff --git a/volk/kernels/volk/volk_32f_s32f_convert_16i.h b/volk/kernels/volk/volk_32f_s32f_convert_16i.h
index 9fd758655f..c11c13b413 100644
--- a/volk/kernels/volk/volk_32f_s32f_convert_16i.h
+++ b/volk/kernels/volk/volk_32f_s32f_convert_16i.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_s32f_convert_16i_u_H
#define INCLUDED_volk_32f_s32f_convert_16i_u_H
@@ -5,6 +27,63 @@
#include <stdio.h>
#include <math.h>
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+ /*!
+ \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 16 bit integer value
+ \param inputVector The floating point input data buffer
+ \param outputVector The 16 bit output data buffer
+ \param scalar The value multiplied against each point in the input buffer
+ \param num_points The number of data values to be converted
+ */
+static inline void volk_32f_s32f_convert_16i_u_avx(int16_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){
+ unsigned int number = 0;
+
+ const unsigned int eighthPoints = num_points / 8;
+
+ const float* inputVectorPtr = (const float*)inputVector;
+ int16_t* outputVectorPtr = outputVector;
+
+ float min_val = -32768;
+ float max_val = 32767;
+ float r;
+
+ __m256 vScalar = _mm256_set1_ps(scalar);
+ __m256 inputVal, ret;
+ __m256i intInputVal;
+ __m128i intInputVal1, intInputVal2;
+ __m256 vmin_val = _mm256_set1_ps(min_val);
+ __m256 vmax_val = _mm256_set1_ps(max_val);
+
+ for(;number < eighthPoints; number++){
+ inputVal = _mm256_loadu_ps(inputVectorPtr); inputVectorPtr += 8;
+
+ // Scale and clip
+ ret = _mm256_max_ps(_mm256_min_ps(_mm256_mul_ps(inputVal, vScalar), vmax_val), vmin_val);
+
+ intInputVal = _mm256_cvtps_epi32(ret);
+
+ intInputVal1 = _mm256_extractf128_si256(intInputVal, 0);
+ intInputVal2 = _mm256_extractf128_si256(intInputVal, 1);
+
+ intInputVal1 = _mm_packs_epi32(intInputVal1, intInputVal2);
+
+ _mm_storeu_si128((__m128i*)outputVectorPtr, intInputVal1);
+ outputVectorPtr += 8;
+ }
+
+ number = eighthPoints * 8;
+ for(; number < num_points; number++){
+ r = inputVector[number] * scalar;
+ if(r > max_val)
+ r = max_val;
+ else if(r < min_val)
+ r = min_val;
+ outputVector[number] = (int16_t)rintf(r);
+ }
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_SSE2
#include <emmintrin.h>
/*!
@@ -158,6 +237,63 @@ static inline void volk_32f_s32f_convert_16i_generic(int16_t* outputVector, cons
#include <stdio.h>
#include <math.h>
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+ /*!
+ \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 16 bit integer value
+ \param inputVector The floating point input data buffer
+ \param outputVector The 16 bit output data buffer
+ \param scalar The value multiplied against each point in the input buffer
+ \param num_points The number of data values to be converted
+ */
+static inline void volk_32f_s32f_convert_16i_a_avx(int16_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){
+ unsigned int number = 0;
+
+ const unsigned int eighthPoints = num_points / 8;
+
+ const float* inputVectorPtr = (const float*)inputVector;
+ int16_t* outputVectorPtr = outputVector;
+
+ float min_val = -32768;
+ float max_val = 32767;
+ float r;
+
+ __m256 vScalar = _mm256_set1_ps(scalar);
+ __m256 inputVal, ret;
+ __m256i intInputVal;
+ __m128i intInputVal1, intInputVal2;
+ __m256 vmin_val = _mm256_set1_ps(min_val);
+ __m256 vmax_val = _mm256_set1_ps(max_val);
+
+ for(;number < eighthPoints; number++){
+ inputVal = _mm256_load_ps(inputVectorPtr); inputVectorPtr += 8;
+
+ // Scale and clip
+ ret = _mm256_max_ps(_mm256_min_ps(_mm256_mul_ps(inputVal, vScalar), vmax_val), vmin_val);
+
+ intInputVal = _mm256_cvtps_epi32(ret);
+
+ intInputVal1 = _mm256_extractf128_si256(intInputVal, 0);
+ intInputVal2 = _mm256_extractf128_si256(intInputVal, 1);
+
+ intInputVal1 = _mm_packs_epi32(intInputVal1, intInputVal2);
+
+ _mm_store_si128((__m128i*)outputVectorPtr, intInputVal1);
+ outputVectorPtr += 8;
+ }
+
+ number = eighthPoints * 8;
+ for(; number < num_points; number++){
+ r = inputVector[number] * scalar;
+ if(r > max_val)
+ r = max_val;
+ else if(r < min_val)
+ r = min_val;
+ outputVector[number] = (int16_t)rintf(r);
+ }
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_SSE2
#include <emmintrin.h>
/*!
diff --git a/volk/kernels/volk/volk_32f_s32f_convert_32i.h b/volk/kernels/volk/volk_32f_s32f_convert_32i.h
index 1a46093ee2..f8e804572f 100644
--- a/volk/kernels/volk/volk_32f_s32f_convert_32i.h
+++ b/volk/kernels/volk/volk_32f_s32f_convert_32i.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_s32f_convert_32i_u_H
#define INCLUDED_volk_32f_s32f_convert_32i_u_H
diff --git a/volk/kernels/volk/volk_32f_s32f_convert_8i.h b/volk/kernels/volk/volk_32f_s32f_convert_8i.h
index b451505221..2f0cee98dd 100644
--- a/volk/kernels/volk/volk_32f_s32f_convert_8i.h
+++ b/volk/kernels/volk/volk_32f_s32f_convert_8i.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_s32f_convert_8i_u_H
#define INCLUDED_volk_32f_s32f_convert_8i_u_H
diff --git a/volk/kernels/volk/volk_32f_s32f_multiply_32f.h b/volk/kernels/volk/volk_32f_s32f_multiply_32f.h
index 8665d4e90e..ee9e2b5c8b 100644
--- a/volk/kernels/volk/volk_32f_s32f_multiply_32f.h
+++ b/volk/kernels/volk/volk_32f_s32f_multiply_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_s32f_multiply_32f_u_H
#define INCLUDED_volk_32f_s32f_multiply_32f_u_H
diff --git a/volk/kernels/volk/volk_32f_s32f_normalize.h b/volk/kernels/volk/volk_32f_s32f_normalize.h
index a0bd33c7dc..95a25f53b4 100644
--- a/volk/kernels/volk/volk_32f_s32f_normalize.h
+++ b/volk/kernels/volk/volk_32f_s32f_normalize.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_s32f_normalize_a_H
#define INCLUDED_volk_32f_s32f_normalize_a_H
diff --git a/volk/kernels/volk/volk_32f_s32f_power_32f.h b/volk/kernels/volk/volk_32f_s32f_power_32f.h
index 2822444686..b8b441311f 100644
--- a/volk/kernels/volk/volk_32f_s32f_power_32f.h
+++ b/volk/kernels/volk/volk_32f_s32f_power_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_s32f_power_32f_a_H
#define INCLUDED_volk_32f_s32f_power_32f_a_H
diff --git a/volk/kernels/volk/volk_32f_s32f_stddev_32f.h b/volk/kernels/volk/volk_32f_s32f_stddev_32f.h
index 0622b278a6..590a7d26f1 100644
--- a/volk/kernels/volk/volk_32f_s32f_stddev_32f.h
+++ b/volk/kernels/volk/volk_32f_s32f_stddev_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_s32f_stddev_32f_a_H
#define INCLUDED_volk_32f_s32f_stddev_32f_a_H
diff --git a/volk/kernels/volk/volk_32f_sin_32f.h b/volk/kernels/volk/volk_32f_sin_32f.h
new file mode 100644
index 0000000000..48ce60c7ed
--- /dev/null
+++ b/volk/kernels/volk/volk_32f_sin_32f.h
@@ -0,0 +1,211 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include <inttypes.h>
+
+#ifndef INCLUDED_volk_32f_sin_32f_a_H
+#define INCLUDED_volk_32f_sin_32f_a_H
+
+#ifdef LV_HAVE_SSE4_1
+#include <smmintrin.h>
+/*!
+ \brief Computes sine of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which sine is to be computed
+*/
+static inline void volk_32f_sin_32f_a_sse4_1(float* bVector, const float* aVector, unsigned int num_points){
+
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+
+ unsigned int number = 0;
+ unsigned int quarterPoints = num_points / 4;
+ unsigned int i = 0;
+
+ __m128 aVal, s, m4pi, pio4A, pio4B, cp1, cp2, cp3, cp4, cp5, ffours, ftwos, fones, fzeroes;
+ __m128 sine, cosine, condition1, condition2;
+ __m128i q, r, ones, twos, fours;
+
+ m4pi = _mm_set1_ps(1.273239545);
+ pio4A = _mm_set1_ps(0.78515625);
+ pio4B = _mm_set1_ps(0.241876e-3);
+ ffours = _mm_set1_ps(4.0);
+ ftwos = _mm_set1_ps(2.0);
+ fones = _mm_set1_ps(1.0);
+ fzeroes = _mm_setzero_ps();
+ ones = _mm_set1_epi32(1);
+ twos = _mm_set1_epi32(2);
+ fours = _mm_set1_epi32(4);
+
+ cp1 = _mm_set1_ps(1.0);
+ cp2 = _mm_set1_ps(0.83333333e-1);
+ cp3 = _mm_set1_ps(0.2777778e-2);
+ cp4 = _mm_set1_ps(0.49603e-4);
+ cp5 = _mm_set1_ps(0.551e-6);
+
+ for(;number < quarterPoints; number++){
+ aVal = _mm_load_ps(aPtr);
+ s = _mm_sub_ps(aVal, _mm_and_ps(_mm_mul_ps(aVal, ftwos), _mm_cmplt_ps(aVal, fzeroes)));
+ q = _mm_cvtps_epi32(_mm_mul_ps(s, m4pi));
+ r = _mm_add_epi32(q, _mm_and_si128(q, ones));
+
+ s = _mm_sub_ps(s, _mm_mul_ps(_mm_cvtepi32_ps(r), pio4A));
+ s = _mm_sub_ps(s, _mm_mul_ps(_mm_cvtepi32_ps(r), pio4B));
+
+ s = _mm_div_ps(s, _mm_set1_ps(8.0)); // The constant is 2^N, for 3 times argument reduction
+ s = _mm_mul_ps(s, s);
+ // Evaluate Taylor series
+ s = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(_mm_sub_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(_mm_sub_ps(_mm_mul_ps(s, cp5), cp4), s), cp3), s), cp2), s), cp1), s);
+
+ for(i = 0; i < 3; i++) {
+ s = _mm_mul_ps(s, _mm_sub_ps(ffours, s));
+ }
+ s = _mm_div_ps(s, ftwos);
+
+ sine = _mm_sqrt_ps(_mm_mul_ps(_mm_sub_ps(ftwos, s), s));
+ cosine = _mm_sub_ps(fones, s);
+
+ condition1 = _mm_cmpneq_ps(_mm_cvtepi32_ps(_mm_and_si128(_mm_add_epi32(q, ones), twos)), fzeroes);
+ condition2 = _mm_cmpneq_ps(_mm_cmpneq_ps(_mm_cvtepi32_ps(_mm_and_si128(q, fours)), fzeroes), _mm_cmplt_ps(aVal, fzeroes));
+ // Need this condition only for cos
+ //condition3 = _mm_cmpneq_ps(_mm_cvtepi32_ps(_mm_and_si128(_mm_add_epi32(q, twos), fours)), fzeroes);
+
+ sine = _mm_add_ps(sine, _mm_and_ps(_mm_sub_ps(cosine, sine), condition1));
+ sine = _mm_sub_ps(sine, _mm_and_ps(_mm_mul_ps(sine, _mm_set1_ps(2.0f)), condition2));
+ _mm_store_ps(bPtr, sine);
+ aPtr += 4;
+ bPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ *bPtr++ = sin(*aPtr++);
+ }
+}
+#endif /* LV_HAVE_SSE4_1 for aligned */
+
+#endif /* INCLUDED_volk_32f_sin_32f_a_H */
+
+#ifndef INCLUDED_volk_32f_sin_32f_u_H
+#define INCLUDED_volk_32f_sin_32f_u_H
+
+#ifdef LV_HAVE_SSE4_1
+#include <smmintrin.h>
+/*!
+ \brief Computes sine of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which sine is to be computed
+*/
+static inline void volk_32f_sin_32f_u_sse4_1(float* bVector, const float* aVector, unsigned int num_points){
+
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+
+ unsigned int number = 0;
+ unsigned int quarterPoints = num_points / 4;
+ unsigned int i = 0;
+
+ __m128 aVal, s, m4pi, pio4A, pio4B, cp1, cp2, cp3, cp4, cp5, ffours, ftwos, fones, fzeroes;
+ __m128 sine, cosine, condition1, condition2;
+ __m128i q, r, ones, twos, fours;
+
+ m4pi = _mm_set1_ps(1.273239545);
+ pio4A = _mm_set1_ps(0.78515625);
+ pio4B = _mm_set1_ps(0.241876e-3);
+ ffours = _mm_set1_ps(4.0);
+ ftwos = _mm_set1_ps(2.0);
+ fones = _mm_set1_ps(1.0);
+ fzeroes = _mm_setzero_ps();
+ ones = _mm_set1_epi32(1);
+ twos = _mm_set1_epi32(2);
+ fours = _mm_set1_epi32(4);
+
+ cp1 = _mm_set1_ps(1.0);
+ cp2 = _mm_set1_ps(0.83333333e-1);
+ cp3 = _mm_set1_ps(0.2777778e-2);
+ cp4 = _mm_set1_ps(0.49603e-4);
+ cp5 = _mm_set1_ps(0.551e-6);
+
+ for(;number < quarterPoints; number++){
+ aVal = _mm_loadu_ps(aPtr);
+ s = _mm_sub_ps(aVal, _mm_and_ps(_mm_mul_ps(aVal, ftwos), _mm_cmplt_ps(aVal, fzeroes)));
+ q = _mm_cvtps_epi32(_mm_mul_ps(s, m4pi));
+ r = _mm_add_epi32(q, _mm_and_si128(q, ones));
+
+ s = _mm_sub_ps(s, _mm_mul_ps(_mm_cvtepi32_ps(r), pio4A));
+ s = _mm_sub_ps(s, _mm_mul_ps(_mm_cvtepi32_ps(r), pio4B));
+
+ s = _mm_div_ps(s, _mm_set1_ps(8.0)); // The constant is 2^N, for 3 times argument reduction
+ s = _mm_mul_ps(s, s);
+ // Evaluate Taylor series
+ s = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(_mm_sub_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(_mm_sub_ps(_mm_mul_ps(s, cp5), cp4), s), cp3), s), cp2), s), cp1), s);
+
+ for(i = 0; i < 3; i++) {
+ s = _mm_mul_ps(s, _mm_sub_ps(ffours, s));
+ }
+ s = _mm_div_ps(s, ftwos);
+
+ sine = _mm_sqrt_ps(_mm_mul_ps(_mm_sub_ps(ftwos, s), s));
+ cosine = _mm_sub_ps(fones, s);
+
+ condition1 = _mm_cmpneq_ps(_mm_cvtepi32_ps(_mm_and_si128(_mm_add_epi32(q, ones), twos)), fzeroes);
+ condition2 = _mm_cmpneq_ps(_mm_cmpneq_ps(_mm_cvtepi32_ps(_mm_and_si128(q, fours)), fzeroes), _mm_cmplt_ps(aVal, fzeroes));
+
+ sine = _mm_add_ps(sine, _mm_and_ps(_mm_sub_ps(cosine, sine), condition1));
+ sine = _mm_sub_ps(sine, _mm_and_ps(_mm_mul_ps(sine, _mm_set1_ps(2.0f)), condition2));
+ _mm_storeu_ps(bPtr, sine);
+ aPtr += 4;
+ bPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ *bPtr++ = sin(*aPtr++);
+ }
+}
+
+#endif /* LV_HAVE_SSE4_1 for unaligned */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Computes sine of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which sine is to be computed
+*/
+static inline void volk_32f_sin_32f_generic(float* bVector, const float* aVector, unsigned int num_points){
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+ unsigned int number = 0;
+
+ for(number = 0; number < num_points; number++){
+ *bPtr++ = sin(*aPtr++);
+ }
+
+}
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_volk_32f_sin_32f_u_H */
diff --git a/volk/kernels/volk/volk_32f_sqrt_32f.h b/volk/kernels/volk/volk_32f_sqrt_32f.h
index f8f8cbd221..fb70b29125 100644
--- a/volk/kernels/volk/volk_32f_sqrt_32f.h
+++ b/volk/kernels/volk/volk_32f_sqrt_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_sqrt_32f_a_H
#define INCLUDED_volk_32f_sqrt_32f_a_H
diff --git a/volk/kernels/volk/volk_32f_stddev_and_mean_32f_x2.h b/volk/kernels/volk/volk_32f_stddev_and_mean_32f_x2.h
index 9bded6713d..9d5f709943 100644
--- a/volk/kernels/volk/volk_32f_stddev_and_mean_32f_x2.h
+++ b/volk/kernels/volk/volk_32f_stddev_and_mean_32f_x2.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_stddev_and_mean_32f_x2_a_H
#define INCLUDED_volk_32f_stddev_and_mean_32f_x2_a_H
diff --git a/volk/kernels/volk/volk_32f_tan_32f.h b/volk/kernels/volk/volk_32f_tan_32f.h
new file mode 100644
index 0000000000..05e52aa809
--- /dev/null
+++ b/volk/kernels/volk/volk_32f_tan_32f.h
@@ -0,0 +1,220 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include <inttypes.h>
+
+#ifndef INCLUDED_volk_32f_tan_32f_a_H
+#define INCLUDED_volk_32f_tan_32f_a_H
+
+#ifdef LV_HAVE_SSE4_1
+#include <smmintrin.h>
+/*!
+ \brief Computes tangent of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which tangent is to be computed
+*/
+static inline void volk_32f_tan_32f_a_sse4_1(float* bVector, const float* aVector, unsigned int num_points){
+
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+
+ unsigned int number = 0;
+ unsigned int quarterPoints = num_points / 4;
+ unsigned int i = 0;
+
+ __m128 aVal, s, m4pi, pio4A, pio4B, cp1, cp2, cp3, cp4, cp5, ffours, ftwos, fones, fzeroes;
+ __m128 sine, cosine, tangent, condition1, condition2, condition3;
+ __m128i q, r, ones, twos, fours;
+
+ m4pi = _mm_set1_ps(1.273239545);
+ pio4A = _mm_set1_ps(0.78515625);
+ pio4B = _mm_set1_ps(0.241876e-3);
+ ffours = _mm_set1_ps(4.0);
+ ftwos = _mm_set1_ps(2.0);
+ fones = _mm_set1_ps(1.0);
+ fzeroes = _mm_setzero_ps();
+ ones = _mm_set1_epi32(1);
+ twos = _mm_set1_epi32(2);
+ fours = _mm_set1_epi32(4);
+
+ cp1 = _mm_set1_ps(1.0);
+ cp2 = _mm_set1_ps(0.83333333e-1);
+ cp3 = _mm_set1_ps(0.2777778e-2);
+ cp4 = _mm_set1_ps(0.49603e-4);
+ cp5 = _mm_set1_ps(0.551e-6);
+
+ for(;number < quarterPoints; number++){
+ aVal = _mm_load_ps(aPtr);
+ s = _mm_sub_ps(aVal, _mm_and_ps(_mm_mul_ps(aVal, ftwos), _mm_cmplt_ps(aVal, fzeroes)));
+ q = _mm_cvtps_epi32(_mm_mul_ps(s, m4pi));
+ r = _mm_add_epi32(q, _mm_and_si128(q, ones));
+
+ s = _mm_sub_ps(s, _mm_mul_ps(_mm_cvtepi32_ps(r), pio4A));
+ s = _mm_sub_ps(s, _mm_mul_ps(_mm_cvtepi32_ps(r), pio4B));
+
+ s = _mm_div_ps(s, _mm_set1_ps(8.0)); // The constant is 2^N, for 3 times argument reduction
+ s = _mm_mul_ps(s, s);
+ // Evaluate Taylor series
+ s = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(_mm_sub_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(_mm_sub_ps(_mm_mul_ps(s, cp5), cp4), s), cp3), s), cp2), s), cp1), s);
+
+ for(i = 0; i < 3; i++){
+ s = _mm_mul_ps(s, _mm_sub_ps(ffours, s));
+ }
+ s = _mm_div_ps(s, ftwos);
+
+ sine = _mm_sqrt_ps(_mm_mul_ps(_mm_sub_ps(ftwos, s), s));
+ cosine = _mm_sub_ps(fones, s);
+
+ condition1 = _mm_cmpneq_ps(_mm_cvtepi32_ps(_mm_and_si128(_mm_add_epi32(q, ones), twos)), fzeroes);
+ condition2 = _mm_cmpneq_ps(_mm_cmpneq_ps(_mm_cvtepi32_ps(_mm_and_si128(q, fours)), fzeroes), _mm_cmplt_ps(aVal, fzeroes));
+ condition3 = _mm_cmpneq_ps(_mm_cvtepi32_ps(_mm_and_si128(_mm_add_epi32(q, twos), fours)), fzeroes);
+
+ __m128 temp = cosine;
+ cosine = _mm_add_ps(cosine, _mm_and_ps(_mm_sub_ps(sine, cosine), condition1));
+ sine = _mm_add_ps(sine, _mm_and_ps(_mm_sub_ps(temp, sine), condition1));
+ sine = _mm_sub_ps(sine, _mm_and_ps(_mm_mul_ps(sine, _mm_set1_ps(2.0f)), condition2));
+ cosine = _mm_sub_ps(cosine, _mm_and_ps(_mm_mul_ps(cosine, _mm_set1_ps(2.0f)), condition3));
+ tangent = _mm_div_ps(sine, cosine);
+ _mm_store_ps(bPtr, tangent);
+ aPtr += 4;
+ bPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ *bPtr++ = tan(*aPtr++);
+ }
+}
+
+#endif /* LV_HAVE_SSE4_1 for aligned */
+
+#endif /* INCLUDED_volk_32f_tan_32f_a_H */
+
+#ifndef INCLUDED_volk_32f_tan_32f_u_H
+#define INCLUDED_volk_32f_tan_32f_u_H
+
+#ifdef LV_HAVE_SSE4_1
+#include <smmintrin.h>
+/*!
+ \brief Computes tangent of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which tangent is to be computed
+*/
+static inline void volk_32f_tan_32f_u_sse4_1(float* bVector, const float* aVector, unsigned int num_points){
+
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+
+ unsigned int number = 0;
+ unsigned int quarterPoints = num_points / 4;
+ unsigned int i = 0;
+
+ __m128 aVal, s, m4pi, pio4A, pio4B, cp1, cp2, cp3, cp4, cp5, ffours, ftwos, fones, fzeroes;
+ __m128 sine, cosine, tangent, condition1, condition2, condition3;
+ __m128i q, r, ones, twos, fours;
+
+ m4pi = _mm_set1_ps(1.273239545);
+ pio4A = _mm_set1_ps(0.78515625);
+ pio4B = _mm_set1_ps(0.241876e-3);
+ ffours = _mm_set1_ps(4.0);
+ ftwos = _mm_set1_ps(2.0);
+ fones = _mm_set1_ps(1.0);
+ fzeroes = _mm_setzero_ps();
+ ones = _mm_set1_epi32(1);
+ twos = _mm_set1_epi32(2);
+ fours = _mm_set1_epi32(4);
+
+ cp1 = _mm_set1_ps(1.0);
+ cp2 = _mm_set1_ps(0.83333333e-1);
+ cp3 = _mm_set1_ps(0.2777778e-2);
+ cp4 = _mm_set1_ps(0.49603e-4);
+ cp5 = _mm_set1_ps(0.551e-6);
+
+ for(;number < quarterPoints; number++){
+ aVal = _mm_loadu_ps(aPtr);
+ s = _mm_sub_ps(aVal, _mm_and_ps(_mm_mul_ps(aVal, ftwos), _mm_cmplt_ps(aVal, fzeroes)));
+ q = _mm_cvtps_epi32(_mm_mul_ps(s, m4pi));
+ r = _mm_add_epi32(q, _mm_and_si128(q, ones));
+
+ s = _mm_sub_ps(s, _mm_mul_ps(_mm_cvtepi32_ps(r), pio4A));
+ s = _mm_sub_ps(s, _mm_mul_ps(_mm_cvtepi32_ps(r), pio4B));
+
+ s = _mm_div_ps(s, _mm_set1_ps(8.0)); // The constant is 2^N, for 3 times argument reduction
+ s = _mm_mul_ps(s, s);
+ // Evaluate Taylor series
+ s = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(_mm_sub_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(_mm_sub_ps(_mm_mul_ps(s, cp5), cp4), s), cp3), s), cp2), s), cp1), s);
+
+ for(i = 0; i < 3; i++){
+ s = _mm_mul_ps(s, _mm_sub_ps(ffours, s));
+ }
+ s = _mm_div_ps(s, ftwos);
+
+ sine = _mm_sqrt_ps(_mm_mul_ps(_mm_sub_ps(ftwos, s), s));
+ cosine = _mm_sub_ps(fones, s);
+
+ condition1 = _mm_cmpneq_ps(_mm_cvtepi32_ps(_mm_and_si128(_mm_add_epi32(q, ones), twos)), fzeroes);
+ condition2 = _mm_cmpneq_ps(_mm_cmpneq_ps(_mm_cvtepi32_ps(_mm_and_si128(q, fours)), fzeroes), _mm_cmplt_ps(aVal, fzeroes));
+ condition3 = _mm_cmpneq_ps(_mm_cvtepi32_ps(_mm_and_si128(_mm_add_epi32(q, twos), fours)), fzeroes);
+
+ __m128 temp = cosine;
+ cosine = _mm_add_ps(cosine, _mm_and_ps(_mm_sub_ps(sine, cosine), condition1));
+ sine = _mm_add_ps(sine, _mm_and_ps(_mm_sub_ps(temp, sine), condition1));
+ sine = _mm_sub_ps(sine, _mm_and_ps(_mm_mul_ps(sine, _mm_set1_ps(2.0f)), condition2));
+ cosine = _mm_sub_ps(cosine, _mm_and_ps(_mm_mul_ps(cosine, _mm_set1_ps(2.0f)), condition3));
+ tangent = _mm_div_ps(sine, cosine);
+ _mm_storeu_ps(bPtr, tangent);
+ aPtr += 4;
+ bPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ *bPtr++ = tan(*aPtr++);
+ }
+}
+
+#endif /* LV_HAVE_SSE4_1 for unaligned */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Computes tangent of input vector and stores results in output vector
+ \param bVector The vector where results will be stored
+ \param aVector The input vector of floats
+ \param num_points Number of points for which tangent is to be computed
+*/
+static inline void volk_32f_tan_32f_generic(float* bVector, const float* aVector, unsigned int num_points){
+ float* bPtr = bVector;
+ const float* aPtr = aVector;
+ unsigned int number = 0;
+
+ for(; number < num_points; number++){
+ *bPtr++ = tan(*aPtr++);
+ }
+
+}
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_volk_32f_tan_32f_u_H */
diff --git a/volk/kernels/volk/volk_32f_tanh_32f.h b/volk/kernels/volk/volk_32f_tanh_32f.h
new file mode 100644
index 0000000000..cdb685f811
--- /dev/null
+++ b/volk/kernels/volk/volk_32f_tanh_32f.h
@@ -0,0 +1,318 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_volk_32f_tanh_32f_a_H
+#define INCLUDED_volk_32f_tanh_32f_a_H
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+
+#ifdef LV_HAVE_GENERIC
+/*!
+\brief Calculates tanh(x)
+\param cVector The vector where the results will be stored
+\param aVector Input vector
+\param num_points The number of values to calulate
+*/
+static inline void volk_32f_tanh_32f_generic(float* cVector, const float* aVector,
+ unsigned int num_points)
+{
+ unsigned int number = 0;
+ float* cPtr = cVector;
+ const float* aPtr = aVector;
+ for(; number < num_points; number++) {
+ *cPtr++ = tanh(*aPtr++);
+ }
+}
+
+#endif /* LV_HAVE_GENERIC */
+
+
+#ifdef LV_HAVE_GENERIC
+/*!
+\brief Calculates tanh(x) using a series approximation, good to within 1e-6 of the actual tanh.
+\param cVector The vector where the results will be stored
+\param aVector Input vector
+\param num_points The number of values to calulate
+*/
+static inline void volk_32f_tanh_32f_series(float* cVector, const float* aVector,
+ unsigned int num_points)
+{
+ unsigned int number = 0;
+ float* cPtr = cVector;
+ const float* aPtr = aVector;
+ for(; number < num_points; number++) {
+ if(*aPtr > 4.97)
+ *cPtr++ = 1;
+ else if(*aPtr <= -4.97)
+ *cPtr++ = -1;
+ else {
+ float x2 = (*aPtr) * (*aPtr);
+ float a = (*aPtr) * (135135.0f + x2 * (17325.0f + x2 * (378.0f + x2)));
+ float b = 135135.0f + x2 * (62370.0f + x2 * (3150.0f + x2 * 28.0f));
+ *cPtr++ = a / b;
+ aPtr++;
+ }
+ }
+}
+
+#endif /* LV_HAVE_GENERIC */
+
+
+
+#ifdef LV_HAVE_SSE
+#include <xmmintrin.h>
+/*!
+\brief Calculates tanh(x) using a series approximation, good to within 1e-6 of the actual tanh.
+\param cVector The vector where the results will be stored
+\param aVector Input vector
+\param num_points The number of values to calulate
+*/
+static inline void volk_32f_tanh_32f_a_sse(float* cVector, const float* aVector,
+ unsigned int num_points)
+{
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ float* cPtr = cVector;
+ const float* aPtr = aVector;
+
+ __m128 aVal, cVal, x2, a, b;
+ __m128 const1, const2, const3, const4, const5, const6;
+ const1 = _mm_set_ps1(135135.0f);
+ const2 = _mm_set_ps1(17325.0f);
+ const3 = _mm_set_ps1(378.0f);
+ const4 = _mm_set_ps1(62370.0f);
+ const5 = _mm_set_ps1(3150.0f);
+ const6 = _mm_set_ps1(28.0f);
+ for(;number < quarterPoints; number++){
+
+ aVal = _mm_load_ps(aPtr);
+ x2 = _mm_mul_ps(aVal, aVal);
+ a = _mm_mul_ps(aVal, _mm_add_ps(const1, _mm_mul_ps(x2, _mm_add_ps(const2, _mm_mul_ps(x2, _mm_add_ps(const3, x2))))));
+ b = _mm_add_ps(const1, _mm_mul_ps(x2, _mm_add_ps(const4, _mm_mul_ps(x2, _mm_add_ps(const5, _mm_mul_ps(x2, const6))))));
+
+ cVal = _mm_div_ps(a, b);
+
+ _mm_store_ps(cPtr, cVal); // Store the results back into the C container
+
+ aPtr += 4;
+ cPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++) {
+ if(*aPtr > 4.97)
+ *cPtr++ = 1;
+ else if(*aPtr <= -4.97)
+ *cPtr++ = -1;
+ else {
+ float x2 = (*aPtr) * (*aPtr);
+ float a = (*aPtr) * (135135.0f + x2 * (17325.0f + x2 * (378.0f + x2)));
+ float b = 135135.0f + x2 * (62370.0f + x2 * (3150.0f + x2 * 28.0f));
+ *cPtr++ = a / b;
+ aPtr++;
+ }
+ }
+}
+#endif /* LV_HAVE_SSE */
+
+
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+/*!
+\brief Calculates tanh(x) using a series approximation, good to within 1e-6 of the actual tanh.
+\param cVector The vector where the results will be stored
+\param aVector Input vector
+\param num_points The number of values to calulate
+*/
+static inline void volk_32f_tanh_32f_a_avx(float* cVector, const float* aVector,
+ unsigned int num_points)
+{
+ unsigned int number = 0;
+ const unsigned int eighthPoints = num_points / 8;
+
+ float* cPtr = cVector;
+ const float* aPtr = aVector;
+
+ __m256 aVal, cVal, x2, a, b;
+ __m256 const1, const2, const3, const4, const5, const6;
+ const1 = _mm256_set1_ps(135135.0f);
+ const2 = _mm256_set1_ps(17325.0f);
+ const3 = _mm256_set1_ps(378.0f);
+ const4 = _mm256_set1_ps(62370.0f);
+ const5 = _mm256_set1_ps(3150.0f);
+ const6 = _mm256_set1_ps(28.0f);
+ for(;number < eighthPoints; number++){
+
+ aVal = _mm256_load_ps(aPtr);
+ x2 = _mm256_mul_ps(aVal, aVal);
+ a = _mm256_mul_ps(aVal, _mm256_add_ps(const1, _mm256_mul_ps(x2, _mm256_add_ps(const2, _mm256_mul_ps(x2, _mm256_add_ps(const3, x2))))));
+ b = _mm256_add_ps(const1, _mm256_mul_ps(x2, _mm256_add_ps(const4, _mm256_mul_ps(x2, _mm256_add_ps(const5, _mm256_mul_ps(x2, const6))))));
+
+ cVal = _mm256_div_ps(a, b);
+
+ _mm256_store_ps(cPtr, cVal); // Store the results back into the C container
+
+ aPtr += 8;
+ cPtr += 8;
+ }
+
+ number = eighthPoints * 8;
+ for(;number < num_points; number++) {
+ if(*aPtr > 4.97)
+ *cPtr++ = 1;
+ else if(*aPtr <= -4.97)
+ *cPtr++ = -1;
+ else {
+ float x2 = (*aPtr) * (*aPtr);
+ float a = (*aPtr) * (135135.0f + x2 * (17325.0f + x2 * (378.0f + x2)));
+ float b = 135135.0f + x2 * (62370.0f + x2 * (3150.0f + x2 * 28.0f));
+ *cPtr++ = a / b;
+ aPtr++;
+ }
+ }
+}
+#endif /* LV_HAVE_AVX */
+
+
+
+
+#ifdef LV_HAVE_SSE
+#include <xmmintrin.h>
+/*!
+\brief Calculates tanh(x) using a series approximation, good to within 1e-6 of the actual tanh.
+\param cVector The vector where the results will be stored
+\param aVector Input vector
+\param num_points The number of values to calulate
+*/
+static inline void volk_32f_tanh_32f_u_sse(float* cVector, const float* aVector,
+ unsigned int num_points)
+{
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ float* cPtr = cVector;
+ const float* aPtr = aVector;
+
+ __m128 aVal, cVal, x2, a, b;
+ __m128 const1, const2, const3, const4, const5, const6;
+ const1 = _mm_set_ps1(135135.0f);
+ const2 = _mm_set_ps1(17325.0f);
+ const3 = _mm_set_ps1(378.0f);
+ const4 = _mm_set_ps1(62370.0f);
+ const5 = _mm_set_ps1(3150.0f);
+ const6 = _mm_set_ps1(28.0f);
+ for(;number < quarterPoints; number++){
+
+ aVal = _mm_loadu_ps(aPtr);
+ x2 = _mm_mul_ps(aVal, aVal);
+ a = _mm_mul_ps(aVal, _mm_add_ps(const1, _mm_mul_ps(x2, _mm_add_ps(const2, _mm_mul_ps(x2, _mm_add_ps(const3, x2))))));
+ b = _mm_add_ps(const1, _mm_mul_ps(x2, _mm_add_ps(const4, _mm_mul_ps(x2, _mm_add_ps(const5, _mm_mul_ps(x2, const6))))));
+
+ cVal = _mm_div_ps(a, b);
+
+ _mm_storeu_ps(cPtr, cVal); // Store the results back into the C container
+
+ aPtr += 4;
+ cPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++) {
+ if(*aPtr > 4.97)
+ *cPtr++ = 1;
+ else if(*aPtr <= -4.97)
+ *cPtr++ = -1;
+ else {
+ float x2 = (*aPtr) * (*aPtr);
+ float a = (*aPtr) * (135135.0f + x2 * (17325.0f + x2 * (378.0f + x2)));
+ float b = 135135.0f + x2 * (62370.0f + x2 * (3150.0f + x2 * 28.0f));
+ *cPtr++ = a / b;
+ aPtr++;
+ }
+ }
+}
+#endif /* LV_HAVE_SSE */
+
+
+
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+/*!
+\brief Calculates tanh(x) using a series approximation, good to within 1e-6 of the actual tanh.
+\param cVector The vector where the results will be stored
+\param aVector Input vector
+\param num_points The number of values to calulate
+*/
+static inline void volk_32f_tanh_32f_u_avx(float* cVector, const float* aVector,
+ unsigned int num_points)
+{
+ unsigned int number = 0;
+ const unsigned int eighthPoints = num_points / 8;
+
+ float* cPtr = cVector;
+ const float* aPtr = aVector;
+
+ __m256 aVal, cVal, x2, a, b;
+ __m256 const1, const2, const3, const4, const5, const6;
+ const1 = _mm256_set1_ps(135135.0f);
+ const2 = _mm256_set1_ps(17325.0f);
+ const3 = _mm256_set1_ps(378.0f);
+ const4 = _mm256_set1_ps(62370.0f);
+ const5 = _mm256_set1_ps(3150.0f);
+ const6 = _mm256_set1_ps(28.0f);
+ for(;number < eighthPoints; number++){
+
+ aVal = _mm256_loadu_ps(aPtr);
+ x2 = _mm256_mul_ps(aVal, aVal);
+ a = _mm256_mul_ps(aVal, _mm256_add_ps(const1, _mm256_mul_ps(x2, _mm256_add_ps(const2, _mm256_mul_ps(x2, _mm256_add_ps(const3, x2))))));
+ b = _mm256_add_ps(const1, _mm256_mul_ps(x2, _mm256_add_ps(const4, _mm256_mul_ps(x2, _mm256_add_ps(const5, _mm256_mul_ps(x2, const6))))));
+
+ cVal = _mm256_div_ps(a, b);
+
+ _mm256_storeu_ps(cPtr, cVal); // Store the results back into the C container
+
+ aPtr += 8;
+ cPtr += 8;
+ }
+
+ number = eighthPoints * 8;
+ for(;number < num_points; number++) {
+ if(*aPtr > 4.97)
+ *cPtr++ = 1;
+ else if(*aPtr <= -4.97)
+ *cPtr++ = -1;
+ else {
+ float x2 = (*aPtr) * (*aPtr);
+ float a = (*aPtr) * (135135.0f + x2 * (17325.0f + x2 * (378.0f + x2)));
+ float b = 135135.0f + x2 * (62370.0f + x2 * (3150.0f + x2 * 28.0f));
+ *cPtr++ = a / b;
+ aPtr++;
+ }
+ }
+}
+#endif /* LV_HAVE_AVX */
+
+#endif /* INCLUDED_volk_32f_tanh_32f_a_H */
diff --git a/volk/kernels/volk/volk_32f_x2_add_32f.h b/volk/kernels/volk/volk_32f_x2_add_32f.h
index a9a1d4fbf0..0c66b271ae 100644
--- a/volk/kernels/volk/volk_32f_x2_add_32f.h
+++ b/volk/kernels/volk/volk_32f_x2_add_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_x2_add_32f_u_H
#define INCLUDED_volk_32f_x2_add_32f_u_H
@@ -136,7 +158,7 @@ static inline void volk_32f_x2_add_32f_u_neon(float* cVector, const float* aVect
// vector add
cVal = vaddq_f32(aVal, bVal);
// Store the results back into the C container
- vst1q_f32(cPtr,cVal);
+ vst1q_f32(cPtr,cVal);
aPtr += 4; // q uses quadwords, 4 floats per vadd
bPtr += 4;
diff --git a/volk/kernels/volk/volk_32f_x2_divide_32f.h b/volk/kernels/volk/volk_32f_x2_divide_32f.h
index d5a7c7d7c0..bbb5cbc9c4 100644
--- a/volk/kernels/volk/volk_32f_x2_divide_32f.h
+++ b/volk/kernels/volk/volk_32f_x2_divide_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_x2_divide_32f_a_H
#define INCLUDED_volk_32f_x2_divide_32f_a_H
diff --git a/volk/kernels/volk/volk_32f_x2_dot_prod_16i.h b/volk/kernels/volk/volk_32f_x2_dot_prod_16i.h
index b637f17777..6e38e33dc7 100644
--- a/volk/kernels/volk/volk_32f_x2_dot_prod_16i.h
+++ b/volk/kernels/volk/volk_32f_x2_dot_prod_16i.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_x2_dot_prod_16i_H
#define INCLUDED_volk_32f_x2_dot_prod_16i_H
diff --git a/volk/kernels/volk/volk_32f_x2_dot_prod_32f.h b/volk/kernels/volk/volk_32f_x2_dot_prod_32f.h
index ac6f56976b..a98802b4b5 100644
--- a/volk/kernels/volk/volk_32f_x2_dot_prod_32f.h
+++ b/volk/kernels/volk/volk_32f_x2_dot_prod_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_x2_dot_prod_32f_u_H
#define INCLUDED_volk_32f_x2_dot_prod_32f_u_H
diff --git a/volk/kernels/volk/volk_32f_x2_interleave_32fc.h b/volk/kernels/volk/volk_32f_x2_interleave_32fc.h
index 3591b24d69..bf7e9250cf 100644
--- a/volk/kernels/volk/volk_32f_x2_interleave_32fc.h
+++ b/volk/kernels/volk/volk_32f_x2_interleave_32fc.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_x2_interleave_32fc_a_H
#define INCLUDED_volk_32f_x2_interleave_32fc_a_H
@@ -70,7 +92,7 @@ static inline void volk_32f_x2_interleave_32fc_neon(lv_32fc_t* complexVector, co
iBuffer += 4;
qBuffer += 4;
complexVectorPtr += 8;
- }
+ }
for(number=quarter_points * 4; number < num_points; ++number) {
*complexVectorPtr++ = *iBuffer++;
diff --git a/volk/kernels/volk/volk_32f_x2_max_32f.h b/volk/kernels/volk/volk_32f_x2_max_32f.h
index a1403fba18..7e4e2afc8e 100644
--- a/volk/kernels/volk/volk_32f_x2_max_32f.h
+++ b/volk/kernels/volk/volk_32f_x2_max_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_x2_max_32f_a_H
#define INCLUDED_volk_32f_x2_max_32f_a_H
@@ -60,7 +82,7 @@ static inline void volk_32f_x2_max_32f_neon(float* cVector, const float* aVector
const float* aPtr = aVector;
const float* bPtr= bVector;
unsigned int number = 0;
-
+
float32x4_t a_vec, b_vec, c_vec;
for(number = 0; number < quarter_points; number++){
a_vec = vld1q_f32(aPtr);
diff --git a/volk/kernels/volk/volk_32f_x2_min_32f.h b/volk/kernels/volk/volk_32f_x2_min_32f.h
index f7598d6354..b67c7b8471 100644
--- a/volk/kernels/volk/volk_32f_x2_min_32f.h
+++ b/volk/kernels/volk/volk_32f_x2_min_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_x2_min_32f_a_H
#define INCLUDED_volk_32f_x2_min_32f_a_H
diff --git a/volk/kernels/volk/volk_32f_x2_multiply_32f.h b/volk/kernels/volk/volk_32f_x2_multiply_32f.h
index 00b31859d6..b05421573d 100644
--- a/volk/kernels/volk/volk_32f_x2_multiply_32f.h
+++ b/volk/kernels/volk/volk_32f_x2_multiply_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_x2_multiply_32f_u_H
#define INCLUDED_volk_32f_x2_multiply_32f_u_H
diff --git a/volk/kernels/volk/volk_32f_x2_pow_32f.h b/volk/kernels/volk/volk_32f_x2_pow_32f.h
new file mode 100644
index 0000000000..431c4c7021
--- /dev/null
+++ b/volk/kernels/volk/volk_32f_x2_pow_32f.h
@@ -0,0 +1,298 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <math.h>
+
+#define POLY0(x, c0) _mm_set1_ps(c0)
+#define POLY1(x, c0, c1) _mm_add_ps(_mm_mul_ps(POLY0(x, c1), x), _mm_set1_ps(c0))
+#define POLY2(x, c0, c1, c2) _mm_add_ps(_mm_mul_ps(POLY1(x, c1, c2), x), _mm_set1_ps(c0))
+#define POLY3(x, c0, c1, c2, c3) _mm_add_ps(_mm_mul_ps(POLY2(x, c1, c2, c3), x), _mm_set1_ps(c0))
+#define POLY4(x, c0, c1, c2, c3, c4) _mm_add_ps(_mm_mul_ps(POLY3(x, c1, c2, c3, c4), x), _mm_set1_ps(c0))
+#define POLY5(x, c0, c1, c2, c3, c4, c5) _mm_add_ps(_mm_mul_ps(POLY4(x, c1, c2, c3, c4, c5), x), _mm_set1_ps(c0))
+
+#define LOG_POLY_DEGREE 3
+
+#ifndef INCLUDED_volk_32f_x2_pow_32f_a_H
+#define INCLUDED_volk_32f_x2_pow_32f_a_H
+
+#ifdef LV_HAVE_SSE4_1
+#include <smmintrin.h>
+/*!
+ \brief Computes pow(x,y) by using exp and log
+ \param cVector The vector where results will be stored
+ \param aVector The input vector of bases
+ \param bVector The input vector of indices
+ \param num_points Number of points for which pow is to be computed
+*/
+static inline void volk_32f_x2_pow_32f_a_sse4_1(float* cVector, const float* bVector, const float* aVector, unsigned int num_points){
+
+ float* cPtr = cVector;
+ const float* bPtr = bVector;
+ const float* aPtr = aVector;
+
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ __m128 aVal, bVal, cVal, logarithm, mantissa, frac, leadingOne;
+ __m128 tmp, fx, mask, pow2n, z, y;
+ __m128 one, exp_hi, exp_lo, ln2, log2EF, half, exp_C1, exp_C2;
+ __m128 exp_p0, exp_p1, exp_p2, exp_p3, exp_p4, exp_p5;
+ __m128i bias, exp, emm0, pi32_0x7f;
+
+ one = _mm_set1_ps(1.0);
+ exp_hi = _mm_set1_ps(88.3762626647949);
+ exp_lo = _mm_set1_ps(-88.3762626647949);
+ ln2 = _mm_set1_ps(0.6931471805);
+ log2EF = _mm_set1_ps(1.44269504088896341);
+ half = _mm_set1_ps(0.5);
+ exp_C1 = _mm_set1_ps(0.693359375);
+ exp_C2 = _mm_set1_ps(-2.12194440e-4);
+ pi32_0x7f = _mm_set1_epi32(0x7f);
+
+ exp_p0 = _mm_set1_ps(1.9875691500e-4);
+ exp_p1 = _mm_set1_ps(1.3981999507e-3);
+ exp_p2 = _mm_set1_ps(8.3334519073e-3);
+ exp_p3 = _mm_set1_ps(4.1665795894e-2);
+ exp_p4 = _mm_set1_ps(1.6666665459e-1);
+ exp_p5 = _mm_set1_ps(5.0000001201e-1);
+
+ for(;number < quarterPoints; number++){
+ // First compute the logarithm
+ aVal = _mm_load_ps(aPtr);
+ bias = _mm_set1_epi32(127);
+ leadingOne = _mm_set1_ps(1.0f);
+ exp = _mm_sub_epi32(_mm_srli_epi32(_mm_and_si128(_mm_castps_si128(aVal), _mm_set1_epi32(0x7f800000)), 23), bias);
+ logarithm = _mm_cvtepi32_ps(exp);
+
+ frac = _mm_or_ps(leadingOne, _mm_and_ps(aVal, _mm_castsi128_ps(_mm_set1_epi32(0x7fffff))));
+
+ #if LOG_POLY_DEGREE == 6
+ mantissa = POLY5( frac, 3.1157899f, -3.3241990f, 2.5988452f, -1.2315303f, 3.1821337e-1f, -3.4436006e-2f);
+ #elif LOG_POLY_DEGREE == 5
+ mantissa = POLY4( frac, 2.8882704548164776201f, -2.52074962577807006663f, 1.48116647521213171641f, -0.465725644288844778798f, 0.0596515482674574969533f);
+ #elif LOG_POLY_DEGREE == 4
+ mantissa = POLY3( frac, 2.61761038894603480148f, -1.75647175389045657003f, 0.688243882994381274313f, -0.107254423828329604454f);
+ #elif LOG_POLY_DEGREE == 3
+ mantissa = POLY2( frac, 2.28330284476918490682f, -1.04913055217340124191f, 0.204446009836232697516f);
+ #else
+ #error
+ #endif
+
+ logarithm = _mm_add_ps(logarithm, _mm_mul_ps(mantissa, _mm_sub_ps(frac, leadingOne)));
+ logarithm = _mm_mul_ps(logarithm, ln2);
+
+
+ // Now calculate b*lna
+ bVal = _mm_load_ps(bPtr);
+ bVal = _mm_mul_ps(bVal, logarithm);
+
+ // Now compute exp(b*lna)
+ tmp = _mm_setzero_ps();
+
+ bVal = _mm_max_ps(_mm_min_ps(bVal, exp_hi), exp_lo);
+
+ fx = _mm_add_ps(_mm_mul_ps(bVal, log2EF), half);
+
+ emm0 = _mm_cvttps_epi32(fx);
+ tmp = _mm_cvtepi32_ps(emm0);
+
+ mask = _mm_and_ps(_mm_cmpgt_ps(tmp, fx), one);
+ fx = _mm_sub_ps(tmp, mask);
+
+ tmp = _mm_mul_ps(fx, exp_C1);
+ z = _mm_mul_ps(fx, exp_C2);
+ bVal = _mm_sub_ps(_mm_sub_ps(bVal, tmp), z);
+ z = _mm_mul_ps(bVal, bVal);
+
+ y = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(exp_p0, bVal), exp_p1), bVal);
+ y = _mm_add_ps(_mm_mul_ps(_mm_add_ps(y, exp_p2), bVal), exp_p3);
+ y = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(y, bVal), exp_p4), bVal);
+ y = _mm_add_ps(_mm_mul_ps(_mm_add_ps(y, exp_p5), z), bVal);
+ y = _mm_add_ps(y, one);
+
+ emm0 = _mm_slli_epi32(_mm_add_epi32(_mm_cvttps_epi32(fx), pi32_0x7f), 23);
+
+ pow2n = _mm_castsi128_ps(emm0);
+ cVal = _mm_mul_ps(y, pow2n);
+
+ _mm_store_ps(cPtr, cVal);
+
+ aPtr += 4;
+ bPtr += 4;
+ cPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ *cPtr++ = pow(*aPtr++, *bPtr++);
+ }
+}
+
+#endif /* LV_HAVE_SSE4_1 for aligned */
+
+#endif /* INCLUDED_volk_32f_x2_pow_32f_a_H */
+
+#ifndef INCLUDED_volk_32f_x2_pow_32f_u_H
+#define INCLUDED_volk_32f_x2_pow_32f_u_H
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Computes pow(x,y) by using exp and log
+ \param cVector The vector where results will be stored
+ \param aVector The input vector of bases
+ \param bVector The input vector of indices
+ \param num_points Number of points for which pow is to be computed
+*/
+static inline void volk_32f_x2_pow_32f_generic(float* cVector, const float* bVector, const float* aVector, unsigned int num_points){
+ float* cPtr = cVector;
+ const float* bPtr = bVector;
+ const float* aPtr = aVector;
+ unsigned int number = 0;
+
+ for(number = 0; number < num_points; number++){
+ *cPtr++ = pow(*aPtr++, *bPtr++);
+ }
+
+}
+#endif /* LV_HAVE_GENERIC */
+
+
+#ifdef LV_HAVE_SSE4_1
+#include <smmintrin.h>
+/*!
+ \brief Computes pow(x,y) by using exp and log
+ \param cVector The vector where results will be stored
+ \param aVector The input vector of bases
+ \param bVector The input vector of indices
+ \param num_points Number of points for which pow is to be computed
+*/
+static inline void volk_32f_x2_pow_32f_u_sse4_1(float* cVector, const float* bVector, const float* aVector, unsigned int num_points){
+
+ float* cPtr = cVector;
+ const float* bPtr = bVector;
+ const float* aPtr = aVector;
+
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ __m128 aVal, bVal, cVal, logarithm, mantissa, frac, leadingOne;
+ __m128 tmp, fx, mask, pow2n, z, y;
+ __m128 one, exp_hi, exp_lo, ln2, log2EF, half, exp_C1, exp_C2;
+ __m128 exp_p0, exp_p1, exp_p2, exp_p3, exp_p4, exp_p5;
+ __m128i bias, exp, emm0, pi32_0x7f;
+
+ one = _mm_set1_ps(1.0);
+ exp_hi = _mm_set1_ps(88.3762626647949);
+ exp_lo = _mm_set1_ps(-88.3762626647949);
+ ln2 = _mm_set1_ps(0.6931471805);
+ log2EF = _mm_set1_ps(1.44269504088896341);
+ half = _mm_set1_ps(0.5);
+ exp_C1 = _mm_set1_ps(0.693359375);
+ exp_C2 = _mm_set1_ps(-2.12194440e-4);
+ pi32_0x7f = _mm_set1_epi32(0x7f);
+
+ exp_p0 = _mm_set1_ps(1.9875691500e-4);
+ exp_p1 = _mm_set1_ps(1.3981999507e-3);
+ exp_p2 = _mm_set1_ps(8.3334519073e-3);
+ exp_p3 = _mm_set1_ps(4.1665795894e-2);
+ exp_p4 = _mm_set1_ps(1.6666665459e-1);
+ exp_p5 = _mm_set1_ps(5.0000001201e-1);
+
+ for(;number < quarterPoints; number++){
+
+ // First compute the logarithm
+ aVal = _mm_loadu_ps(aPtr);
+ bias = _mm_set1_epi32(127);
+ leadingOne = _mm_set1_ps(1.0f);
+ exp = _mm_sub_epi32(_mm_srli_epi32(_mm_and_si128(_mm_castps_si128(aVal), _mm_set1_epi32(0x7f800000)), 23), bias);
+ logarithm = _mm_cvtepi32_ps(exp);
+
+ frac = _mm_or_ps(leadingOne, _mm_and_ps(aVal, _mm_castsi128_ps(_mm_set1_epi32(0x7fffff))));
+
+ #if LOG_POLY_DEGREE == 6
+ mantissa = POLY5( frac, 3.1157899f, -3.3241990f, 2.5988452f, -1.2315303f, 3.1821337e-1f, -3.4436006e-2f);
+ #elif LOG_POLY_DEGREE == 5
+ mantissa = POLY4( frac, 2.8882704548164776201f, -2.52074962577807006663f, 1.48116647521213171641f, -0.465725644288844778798f, 0.0596515482674574969533f);
+ #elif LOG_POLY_DEGREE == 4
+ mantissa = POLY3( frac, 2.61761038894603480148f, -1.75647175389045657003f, 0.688243882994381274313f, -0.107254423828329604454f);
+ #elif LOG_POLY_DEGREE == 3
+ mantissa = POLY2( frac, 2.28330284476918490682f, -1.04913055217340124191f, 0.204446009836232697516f);
+ #else
+ #error
+ #endif
+
+ logarithm = _mm_add_ps(logarithm, _mm_mul_ps(mantissa, _mm_sub_ps(frac, leadingOne)));
+ logarithm = _mm_mul_ps(logarithm, ln2);
+
+
+ // Now calculate b*lna
+ bVal = _mm_loadu_ps(bPtr);
+ bVal = _mm_mul_ps(bVal, logarithm);
+
+ // Now compute exp(b*lna)
+ tmp = _mm_setzero_ps();
+
+ bVal = _mm_max_ps(_mm_min_ps(bVal, exp_hi), exp_lo);
+
+ fx = _mm_add_ps(_mm_mul_ps(bVal, log2EF), half);
+
+ emm0 = _mm_cvttps_epi32(fx);
+ tmp = _mm_cvtepi32_ps(emm0);
+
+ mask = _mm_and_ps(_mm_cmpgt_ps(tmp, fx), one);
+ fx = _mm_sub_ps(tmp, mask);
+
+ tmp = _mm_mul_ps(fx, exp_C1);
+ z = _mm_mul_ps(fx, exp_C2);
+ bVal = _mm_sub_ps(_mm_sub_ps(bVal, tmp), z);
+ z = _mm_mul_ps(bVal, bVal);
+
+ y = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(exp_p0, bVal), exp_p1), bVal);
+ y = _mm_add_ps(_mm_mul_ps(_mm_add_ps(y, exp_p2), bVal), exp_p3);
+ y = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(y, bVal), exp_p4), bVal);
+ y = _mm_add_ps(_mm_mul_ps(_mm_add_ps(y, exp_p5), z), bVal);
+ y = _mm_add_ps(y, one);
+
+ emm0 = _mm_slli_epi32(_mm_add_epi32(_mm_cvttps_epi32(fx), pi32_0x7f), 23);
+
+ pow2n = _mm_castsi128_ps(emm0);
+ cVal = _mm_mul_ps(y, pow2n);
+
+ _mm_storeu_ps(cPtr, cVal);
+
+ aPtr += 4;
+ bPtr += 4;
+ cPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ *cPtr++ = pow(*aPtr++, *bPtr++);
+ }
+}
+
+#endif /* LV_HAVE_SSE4_1 for unaligned */
+
+#endif /* INCLUDED_volk_32f_x2_log2_32f_u_H */
diff --git a/volk/kernels/volk/volk_32f_x2_s32f_interleave_16ic.h b/volk/kernels/volk/volk_32f_x2_s32f_interleave_16ic.h
index ce7b91a318..5d7eca8f4c 100644
--- a/volk/kernels/volk/volk_32f_x2_s32f_interleave_16ic.h
+++ b/volk/kernels/volk/volk_32f_x2_s32f_interleave_16ic.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_x2_s32f_interleave_16ic_a_H
#define INCLUDED_volk_32f_x2_s32f_interleave_16ic_a_H
diff --git a/volk/kernels/volk/volk_32f_x2_subtract_32f.h b/volk/kernels/volk/volk_32f_x2_subtract_32f.h
index c725ef8d4f..a3aa8e0d6b 100644
--- a/volk/kernels/volk/volk_32f_x2_subtract_32f.h
+++ b/volk/kernels/volk/volk_32f_x2_subtract_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_x2_subtract_32f_a_H
#define INCLUDED_volk_32f_x2_subtract_32f_a_H
diff --git a/volk/kernels/volk/volk_32f_x3_sum_of_poly_32f.h b/volk/kernels/volk/volk_32f_x3_sum_of_poly_32f.h
index 0d3c2168c7..cc40c67a66 100644
--- a/volk/kernels/volk/volk_32f_x3_sum_of_poly_32f.h
+++ b/volk/kernels/volk/volk_32f_x3_sum_of_poly_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32f_x3_sum_of_poly_32f_a_H
#define INCLUDED_volk_32f_x3_sum_of_poly_32f_a_H
diff --git a/volk/kernels/volk/volk_32fc_32f_dot_prod_32fc.h b/volk/kernels/volk/volk_32fc_32f_dot_prod_32fc.h
index 6d0c8480e0..0c3ef0d8b7 100644
--- a/volk/kernels/volk/volk_32fc_32f_dot_prod_32fc.h
+++ b/volk/kernels/volk/volk_32fc_32f_dot_prod_32fc.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_32f_dot_prod_32fc_a_H
#define INCLUDED_volk_32fc_32f_dot_prod_32fc_a_H
@@ -296,7 +318,7 @@ static inline void volk_32fc_32f_dot_prod_32fc_neon_unroll ( lv_32fc_t* __restri
const float* inputPtr = (float*)input;
const float* tapsPtr = taps;
float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f };
- float accVector_real[4];
+ float accVector_real[4];
float accVector_imag[4];
float32x4x2_t inputVector0, inputVector1;
@@ -305,14 +327,14 @@ static inline void volk_32fc_32f_dot_prod_32fc_neon_unroll ( lv_32fc_t* __restri
float32x4_t tmp_real1, tmp_imag1;
float32x4_t real_accumulator0, imag_accumulator0;
float32x4_t real_accumulator1, imag_accumulator1;
-
+
// zero out accumulators
// take a *float, return float32x4_t
real_accumulator0 = vld1q_f32( zero );
imag_accumulator0 = vld1q_f32( zero );
real_accumulator1 = vld1q_f32( zero );
imag_accumulator1 = vld1q_f32( zero );
-
+
for(number=0 ;number < quarterPoints; number++){
// load doublewords and duplicate in to second lane
tapsVector0 = vld1q_f32(tapsPtr );
@@ -338,7 +360,7 @@ static inline void volk_32fc_32f_dot_prod_32fc_neon_unroll ( lv_32fc_t* __restri
tapsPtr += 8;
inputPtr += 16;
}
-
+
real_accumulator0 = vaddq_f32( real_accumulator0, real_accumulator1);
imag_accumulator0 = vaddq_f32( imag_accumulator0, imag_accumulator1);
// void vst1q_f32( float32_t * ptr, float32x4_t val);
diff --git a/volk/kernels/volk/volk_32fc_32f_multiply_32fc.h b/volk/kernels/volk/volk_32fc_32f_multiply_32fc.h
index 21b71998c2..0f5a141107 100644
--- a/volk/kernels/volk/volk_32fc_32f_multiply_32fc.h
+++ b/volk/kernels/volk/volk_32fc_32f_multiply_32fc.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_32f_multiply_32fc_a_H
#define INCLUDED_volk_32fc_32f_multiply_32fc_a_H
diff --git a/volk/kernels/volk/volk_32fc_conjugate_32fc.h b/volk/kernels/volk/volk_32fc_conjugate_32fc.h
index 0f74b01816..49d8a0fbda 100644
--- a/volk/kernels/volk/volk_32fc_conjugate_32fc.h
+++ b/volk/kernels/volk/volk_32fc_conjugate_32fc.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_conjugate_32fc_u_H
#define INCLUDED_volk_32fc_conjugate_32fc_u_H
@@ -6,6 +28,44 @@
#include <volk/volk_complex.h>
#include <float.h>
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+ /*!
+ \brief Takes the conjugate of a complex vector.
+ \param cVector The vector where the results will be stored
+ \param aVector Vector to be conjugated
+ \param num_points The number of complex values in aVector to be conjugated and stored into cVector
+ */
+static inline void volk_32fc_conjugate_32fc_u_avx(lv_32fc_t* cVector, const lv_32fc_t* aVector, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ __m256 x;
+ lv_32fc_t* c = cVector;
+ const lv_32fc_t* a = aVector;
+
+ __m256 conjugator = _mm256_setr_ps(0, -0.f, 0, -0.f, 0, -0.f, 0, -0.f);
+
+ for(;number < quarterPoints; number++){
+
+ x = _mm256_loadu_ps((float*)a); // Load the complex data as ar,ai,br,bi
+
+ x = _mm256_xor_ps(x, conjugator); // conjugate register
+
+ _mm256_storeu_ps((float*)c,x); // Store the results back into the C container
+
+ a += 4;
+ c += 4;
+ }
+
+ number = quarterPoints * 4;
+
+ for(;number < num_points; number++) {
+ *c++ = lv_conj(*a++);
+ }
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_SSE3
#include <pmmintrin.h>
/*!
@@ -70,6 +130,44 @@ static inline void volk_32fc_conjugate_32fc_generic(lv_32fc_t* cVector, const lv
#include <volk/volk_complex.h>
#include <float.h>
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+ /*!
+ \brief Takes the conjugate of a complex vector.
+ \param cVector The vector where the results will be stored
+ \param aVector Vector to be conjugated
+ \param num_points The number of complex values in aVector to be conjugated and stored into cVector
+ */
+static inline void volk_32fc_conjugate_32fc_a_avx(lv_32fc_t* cVector, const lv_32fc_t* aVector, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ __m256 x;
+ lv_32fc_t* c = cVector;
+ const lv_32fc_t* a = aVector;
+
+ __m256 conjugator = _mm256_setr_ps(0, -0.f, 0, -0.f, 0, -0.f, 0, -0.f);
+
+ for(;number < quarterPoints; number++){
+
+ x = _mm256_load_ps((float*)a); // Load the complex data as ar,ai,br,bi
+
+ x = _mm256_xor_ps(x, conjugator); // conjugate register
+
+ _mm256_store_ps((float*)c,x); // Store the results back into the C container
+
+ a += 4;
+ c += 4;
+ }
+
+ number = quarterPoints * 4;
+
+ for(;number < num_points; number++) {
+ *c++ = lv_conj(*a++);
+ }
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_SSE3
#include <pmmintrin.h>
/*!
diff --git a/volk/kernels/volk/volk_32fc_deinterleave_32f_x2.h b/volk/kernels/volk/volk_32fc_deinterleave_32f_x2.h
index 0d33ed7e28..aed7f097b8 100644
--- a/volk/kernels/volk/volk_32fc_deinterleave_32f_x2.h
+++ b/volk/kernels/volk/volk_32fc_deinterleave_32f_x2.h
@@ -1,9 +1,80 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_deinterleave_32f_x2_a_H
#define INCLUDED_volk_32fc_deinterleave_32f_x2_a_H
#include <inttypes.h>
#include <stdio.h>
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+/*!
+ \brief Deinterleaves the complex vector into I & Q vector data
+ \param complexVector The complex input vector
+ \param iBuffer The I buffer output data
+ \param qBuffer The Q buffer output data
+ \param num_points The number of complex data values to be deinterleaved
+*/
+static inline void volk_32fc_deinterleave_32f_x2_a_avx(float* iBuffer, float* qBuffer, const lv_32fc_t* complexVector, unsigned int num_points){
+ const float* complexVectorPtr = (float*)complexVector;
+ float* iBufferPtr = iBuffer;
+ float* qBufferPtr = qBuffer;
+
+ unsigned int number = 0;
+ // Mask for real and imaginary parts
+ const unsigned int eighthPoints = num_points / 8;
+ __m256 cplxValue1, cplxValue2, complex1, complex2, iValue, qValue;
+ for(;number < eighthPoints; number++){
+
+ cplxValue1 = _mm256_load_ps(complexVectorPtr);
+ complexVectorPtr += 8;
+
+ cplxValue2 = _mm256_load_ps(complexVectorPtr);
+ complexVectorPtr += 8;
+
+ complex1 = _mm256_permute2f128_ps(cplxValue1, cplxValue2, 0x20);
+ complex2 = _mm256_permute2f128_ps(cplxValue1, cplxValue2, 0x31);
+
+ // Arrange in i1i2i3i4 format
+ iValue = _mm256_shuffle_ps(complex1, complex2, 0x88);
+ // Arrange in q1q2q3q4 format
+ qValue = _mm256_shuffle_ps(complex1, complex2, 0xdd);
+
+ _mm256_store_ps(iBufferPtr, iValue);
+ _mm256_store_ps(qBufferPtr, qValue);
+
+ iBufferPtr += 8;
+ qBufferPtr += 8;
+ }
+
+ number = eighthPoints * 8;
+ for(; number < num_points; number++){
+ *iBufferPtr++ = *complexVectorPtr++;
+ *qBufferPtr++ = *complexVectorPtr++;
+ }
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_SSE
#include <xmmintrin.h>
/*!
@@ -49,6 +120,39 @@ static inline void volk_32fc_deinterleave_32f_x2_a_sse(float* iBuffer, float* qB
}
#endif /* LV_HAVE_SSE */
+#ifdef LV_HAVE_NEON
+#include <arm_neon.h>
+/*!
+ \brief Deinterleaves the complex vector into I & Q vector data
+ \param complexVector The complex input vector
+ \param iBuffer The I buffer output data
+ \param qBuffer The Q buffer output data
+ \param num_points The number of complex data values to be deinterleaved
+*/
+static inline void volk_32fc_deinterleave_32f_x2_neon(float* iBuffer, float* qBuffer, const lv_32fc_t* complexVector, unsigned int num_points){
+ unsigned int number = 0;
+ unsigned int quarter_points = num_points / 4;
+ const float* complexVectorPtr = (float*)complexVector;
+ float* iBufferPtr = iBuffer;
+ float* qBufferPtr = qBuffer;
+ float32x4x2_t complexInput;
+
+ for(number = 0; number < quarter_points; number++){
+ complexInput = vld2q_f32(complexVectorPtr);
+ vst1q_f32( iBufferPtr, complexInput.val[0] );
+ vst1q_f32( qBufferPtr, complexInput.val[1] );
+ complexVectorPtr += 8;
+ iBufferPtr += 4;
+ qBufferPtr += 4;
+ }
+
+ for(number = quarter_points*4; number < num_points; number++){
+ *iBufferPtr++ = *complexVectorPtr++;
+ *qBufferPtr++ = *complexVectorPtr++;
+ }
+}
+#endif /* LV_HAVE_NEON */
+
#ifdef LV_HAVE_GENERIC
/*!
\brief Deinterleaves the complex vector into I & Q vector data
diff --git a/volk/kernels/volk/volk_32fc_deinterleave_64f_x2.h b/volk/kernels/volk/volk_32fc_deinterleave_64f_x2.h
index 4a4c5509bd..9b872e05e2 100644
--- a/volk/kernels/volk/volk_32fc_deinterleave_64f_x2.h
+++ b/volk/kernels/volk/volk_32fc_deinterleave_64f_x2.h
@@ -1,9 +1,82 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_deinterleave_64f_x2_u_H
#define INCLUDED_volk_32fc_deinterleave_64f_x2_u_H
#include <inttypes.h>
#include <stdio.h>
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+/*!
+ \brief Deinterleaves the lv_32fc_t vector into double I & Q vector data
+ \param complexVector The complex input vector
+ \param iBuffer The I buffer output data
+ \param qBuffer The Q buffer output data
+ \param num_points The number of complex data values to be deinterleaved
+*/
+static inline void volk_32fc_deinterleave_64f_x2_u_avx(double* iBuffer, double* qBuffer, const lv_32fc_t* complexVector, unsigned int num_points){
+ unsigned int number = 0;
+
+ const float* complexVectorPtr = (float*)complexVector;
+ double* iBufferPtr = iBuffer;
+ double* qBufferPtr = qBuffer;
+
+ const unsigned int quarterPoints = num_points / 4;
+ __m256 cplxValue;
+ __m128 complexH, complexL, fVal;
+ __m256d dVal;
+
+ for(;number < quarterPoints; number++){
+
+ cplxValue = _mm256_loadu_ps(complexVectorPtr);
+ complexVectorPtr += 8;
+
+ complexH = _mm256_extractf128_ps(cplxValue, 1);
+ complexL = _mm256_extractf128_ps(cplxValue, 0);
+
+ // Arrange in i1i2i1i2 format
+ fVal = _mm_shuffle_ps(complexL, complexH, _MM_SHUFFLE(2,0,2,0));
+ dVal = _mm256_cvtps_pd(fVal);
+ _mm256_storeu_pd(iBufferPtr, dVal);
+
+ // Arrange in q1q2q1q2 format
+ fVal = _mm_shuffle_ps(complexL, complexH, _MM_SHUFFLE(3,1,3,1));
+ dVal = _mm256_cvtps_pd(fVal);
+ _mm256_storeu_pd(qBufferPtr, dVal);
+
+ iBufferPtr += 4;
+ qBufferPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(; number < num_points; number++){
+ *iBufferPtr++ = *complexVectorPtr++;
+ *qBufferPtr++ = *complexVectorPtr++;
+ }
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_SSE2
#include <emmintrin.h>
/*!
@@ -82,6 +155,57 @@ static inline void volk_32fc_deinterleave_64f_x2_generic(double* iBuffer, double
#include <inttypes.h>
#include <stdio.h>
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+/*!
+ \brief Deinterleaves the lv_32fc_t vector into double I & Q vector data
+ \param complexVector The complex input vector
+ \param iBuffer The I buffer output data
+ \param qBuffer The Q buffer output data
+ \param num_points The number of complex data values to be deinterleaved
+*/
+static inline void volk_32fc_deinterleave_64f_x2_a_avx(double* iBuffer, double* qBuffer, const lv_32fc_t* complexVector, unsigned int num_points){
+ unsigned int number = 0;
+
+ const float* complexVectorPtr = (float*)complexVector;
+ double* iBufferPtr = iBuffer;
+ double* qBufferPtr = qBuffer;
+
+ const unsigned int quarterPoints = num_points / 4;
+ __m256 cplxValue;
+ __m128 complexH, complexL, fVal;
+ __m256d dVal;
+
+ for(;number < quarterPoints; number++){
+
+ cplxValue = _mm256_load_ps(complexVectorPtr);
+ complexVectorPtr += 8;
+
+ complexH = _mm256_extractf128_ps(cplxValue, 1);
+ complexL = _mm256_extractf128_ps(cplxValue, 0);
+
+ // Arrange in i1i2i1i2 format
+ fVal = _mm_shuffle_ps(complexL, complexH, _MM_SHUFFLE(2,0,2,0));
+ dVal = _mm256_cvtps_pd(fVal);
+ _mm256_store_pd(iBufferPtr, dVal);
+
+ // Arrange in q1q2q1q2 format
+ fVal = _mm_shuffle_ps(complexL, complexH, _MM_SHUFFLE(3,1,3,1));
+ dVal = _mm256_cvtps_pd(fVal);
+ _mm256_store_pd(qBufferPtr, dVal);
+
+ iBufferPtr += 4;
+ qBufferPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(; number < num_points; number++){
+ *iBufferPtr++ = *complexVectorPtr++;
+ *qBufferPtr++ = *complexVectorPtr++;
+ }
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_SSE2
#include <emmintrin.h>
/*!
diff --git a/volk/kernels/volk/volk_32fc_deinterleave_imag_32f.h b/volk/kernels/volk/volk_32fc_deinterleave_imag_32f.h
index b1968296f5..a590c83d7a 100644
--- a/volk/kernels/volk/volk_32fc_deinterleave_imag_32f.h
+++ b/volk/kernels/volk/volk_32fc_deinterleave_imag_32f.h
@@ -1,9 +1,73 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_deinterleave_imag_32f_a_H
#define INCLUDED_volk_32fc_deinterleave_imag_32f_a_H
#include <inttypes.h>
#include <stdio.h>
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+/*!
+ \brief Deinterleaves the complex vector into Q vector data
+ \param complexVector The complex input vector
+ \param qBuffer The Q buffer output data
+ \param num_points The number of complex data values to be deinterleaved
+*/
+static inline void volk_32fc_deinterleave_imag_32f_a_avx(float* qBuffer, const lv_32fc_t* complexVector, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int eighthPoints = num_points / 8;
+ const float* complexVectorPtr = (const float*)complexVector;
+ float* qBufferPtr = qBuffer;
+
+ __m256 cplxValue1, cplxValue2, complex1, complex2, qValue;
+ for(;number < eighthPoints; number++){
+
+ cplxValue1 = _mm256_load_ps(complexVectorPtr);
+ complexVectorPtr += 8;
+
+ cplxValue2 = _mm256_load_ps(complexVectorPtr);
+ complexVectorPtr += 8;
+
+ complex1 = _mm256_permute2f128_ps(cplxValue1, cplxValue2, 0x20);
+ complex2 = _mm256_permute2f128_ps(cplxValue1, cplxValue2, 0x31);
+
+ // Arrange in q1q2q3q4 format
+ qValue = _mm256_shuffle_ps(complex1, complex2, 0xdd);
+
+ _mm256_store_ps(qBufferPtr, qValue);
+
+ qBufferPtr += 8;
+ }
+
+ number = eighthPoints * 8;
+ for(; number < num_points; number++){
+ complexVectorPtr++;
+ *qBufferPtr++ = *complexVectorPtr++;
+ }
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_SSE
#include <xmmintrin.h>
/*!
@@ -44,6 +108,35 @@ static inline void volk_32fc_deinterleave_imag_32f_a_sse(float* qBuffer, const l
}
#endif /* LV_HAVE_SSE */
+#ifdef LV_HAVE_NEON
+#include <arm_neon.h>
+/*!
+ \brief Deinterleaves the complex vector into Q vector data
+ \param complexVector The complex input vector
+ \param qBuffer The Q buffer output data
+ \param num_points The number of complex data values to be deinterleaved
+*/
+static inline void volk_32fc_deinterleave_imag_32f_neon(float* qBuffer, const lv_32fc_t* complexVector, unsigned int num_points){
+ unsigned int number = 0;
+ unsigned int quarter_points = num_points / 4;
+ const float* complexVectorPtr = (float*)complexVector;
+ float* qBufferPtr = qBuffer;
+ float32x4x2_t complexInput;
+
+ for(number = 0; number < quarter_points; number++){
+ complexInput = vld2q_f32(complexVectorPtr);
+ vst1q_f32( qBufferPtr, complexInput.val[1] );
+ complexVectorPtr += 8;
+ qBufferPtr += 4;
+ }
+
+ for(number = quarter_points*4; number < num_points; number++){
+ complexVectorPtr++;
+ *qBufferPtr++ = *complexVectorPtr++;
+ }
+}
+#endif /* LV_HAVE_NEON */
+
#ifdef LV_HAVE_GENERIC
/*!
\brief Deinterleaves the complex vector into Q vector data
diff --git a/volk/kernels/volk/volk_32fc_deinterleave_real_32f.h b/volk/kernels/volk/volk_32fc_deinterleave_real_32f.h
index 3d57598135..c0e8d8fb34 100644
--- a/volk/kernels/volk/volk_32fc_deinterleave_real_32f.h
+++ b/volk/kernels/volk/volk_32fc_deinterleave_real_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_deinterleave_real_32f_a_H
#define INCLUDED_volk_32fc_deinterleave_real_32f_a_H
@@ -62,7 +84,33 @@ static inline void volk_32fc_deinterleave_real_32f_generic(float* iBuffer, const
}
#endif /* LV_HAVE_GENERIC */
+#ifdef LV_HAVE_NEON
+#include <arm_neon.h>
+/*!
+ \brief Deinterleaves the complex vector into I vector data
+ \param complexVector The complex input vector
+ \param iBuffer The I buffer output data
+ \param num_points The number of complex data values to be deinterleaved
+*/
+static inline void volk_32fc_deinterleave_real_32f_neon(float* iBuffer, const lv_32fc_t* complexVector, unsigned int num_points){
+ unsigned int number = 0;
+ unsigned int quarter_points = num_points / 4;
+ const float* complexVectorPtr = (float*)complexVector;
+ float* iBufferPtr = iBuffer;
+ float32x4x2_t complexInput;
+ for(number = 0; number < quarter_points; number++){
+ complexInput = vld2q_f32(complexVectorPtr);
+ vst1q_f32( iBufferPtr, complexInput.val[0] );
+ complexVectorPtr += 8;
+ iBufferPtr += 4;
+ }
+ for(number = quarter_points*4; number < num_points; number++){
+ *iBufferPtr++ = *complexVectorPtr++;
+ complexVectorPtr++;
+ }
+}
+#endif /* LV_HAVE_NEON */
#endif /* INCLUDED_volk_32fc_deinterleave_real_32f_a_H */
diff --git a/volk/kernels/volk/volk_32fc_deinterleave_real_64f.h b/volk/kernels/volk/volk_32fc_deinterleave_real_64f.h
index 1fa66e8add..eb1df386a8 100644
--- a/volk/kernels/volk/volk_32fc_deinterleave_real_64f.h
+++ b/volk/kernels/volk/volk_32fc_deinterleave_real_64f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_deinterleave_real_64f_a_H
#define INCLUDED_volk_32fc_deinterleave_real_64f_a_H
diff --git a/volk/kernels/volk/volk_32fc_index_max_16u.h b/volk/kernels/volk/volk_32fc_index_max_16u.h
index c8d7212401..bc47f7983b 100644
--- a/volk/kernels/volk/volk_32fc_index_max_16u.h
+++ b/volk/kernels/volk/volk_32fc_index_max_16u.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_index_max_16u_a_H
#define INCLUDED_volk_32fc_index_max_16u_a_H
diff --git a/volk/kernels/volk/volk_32fc_magnitude_32f.h b/volk/kernels/volk/volk_32fc_magnitude_32f.h
index b6da7f3630..d057b70f5e 100644
--- a/volk/kernels/volk/volk_32fc_magnitude_32f.h
+++ b/volk/kernels/volk/volk_32fc_magnitude_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_magnitude_32f_u_H
#define INCLUDED_volk_32fc_magnitude_32f_u_H
@@ -5,6 +27,52 @@
#include <stdio.h>
#include <math.h>
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+ /*!
+ \brief Calculates the magnitude of the complexVector and stores the results in the magnitudeVector
+ \param complexVector The vector containing the complex input values
+ \param magnitudeVector The vector containing the real output values
+ \param num_points The number of complex values in complexVector to be calculated and stored into cVector
+ */
+static inline void volk_32fc_magnitude_32f_u_avx(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int eighthPoints = num_points / 8;
+
+ const float* complexVectorPtr = (float*)complexVector;
+ float* magnitudeVectorPtr = magnitudeVector;
+
+ __m256 cplxValue1, cplxValue2, complex1, complex2, result;
+ for(;number < eighthPoints; number++){
+ cplxValue1 = _mm256_loadu_ps(complexVectorPtr);
+ complexVectorPtr += 8;
+
+ cplxValue2 = _mm256_loadu_ps(complexVectorPtr);
+ complexVectorPtr += 8;
+
+ cplxValue1 = _mm256_mul_ps(cplxValue1, cplxValue1); // Square the values
+ cplxValue2 = _mm256_mul_ps(cplxValue2, cplxValue2); // Square the Values
+
+ complex1 = _mm256_permute2f128_ps(cplxValue1, cplxValue2, 0x20);
+ complex2 = _mm256_permute2f128_ps(cplxValue1, cplxValue2, 0x31);
+
+ result = _mm256_hadd_ps(complex1, complex2); // Add the I2 and Q2 values
+
+ result = _mm256_sqrt_ps(result);
+
+ _mm256_storeu_ps(magnitudeVectorPtr, result);
+ magnitudeVectorPtr += 8;
+ }
+
+ number = eighthPoints * 8;
+ for(; number < num_points; number++){
+ float val1Real = *complexVectorPtr++;
+ float val1Imag = *complexVectorPtr++;
+ *magnitudeVectorPtr++ = sqrtf((val1Real * val1Real) + (val1Imag * val1Imag));
+ }
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_SSE3
#include <pmmintrin.h>
/*!
@@ -123,6 +191,52 @@ static inline void volk_32fc_magnitude_32f_generic(float* magnitudeVector, const
#include <stdio.h>
#include <math.h>
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+ /*!
+ \brief Calculates the magnitude of the complexVector and stores the results in the magnitudeVector
+ \param complexVector The vector containing the complex input values
+ \param magnitudeVector The vector containing the real output values
+ \param num_points The number of complex values in complexVector to be calculated and stored into cVector
+ */
+static inline void volk_32fc_magnitude_32f_a_avx(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int eighthPoints = num_points / 8;
+
+ const float* complexVectorPtr = (float*)complexVector;
+ float* magnitudeVectorPtr = magnitudeVector;
+
+ __m256 cplxValue1, cplxValue2, complex1, complex2, result;
+ for(;number < eighthPoints; number++){
+ cplxValue1 = _mm256_load_ps(complexVectorPtr);
+ complexVectorPtr += 8;
+
+ cplxValue2 = _mm256_load_ps(complexVectorPtr);
+ complexVectorPtr += 8;
+
+ cplxValue1 = _mm256_mul_ps(cplxValue1, cplxValue1); // Square the values
+ cplxValue2 = _mm256_mul_ps(cplxValue2, cplxValue2); // Square the Values
+
+ complex1 = _mm256_permute2f128_ps(cplxValue1, cplxValue2, 0x20);
+ complex2 = _mm256_permute2f128_ps(cplxValue1, cplxValue2, 0x31);
+
+ result = _mm256_hadd_ps(complex1, complex2); // Add the I2 and Q2 values
+
+ result = _mm256_sqrt_ps(result);
+
+ _mm256_store_ps(magnitudeVectorPtr, result);
+ magnitudeVectorPtr += 8;
+ }
+
+ number = eighthPoints * 8;
+ for(; number < num_points; number++){
+ float val1Real = *complexVectorPtr++;
+ float val1Imag = *complexVectorPtr++;
+ *magnitudeVectorPtr++ = sqrtf((val1Real * val1Real) + (val1Imag * val1Imag));
+ }
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_SSE3
#include <pmmintrin.h>
/*!
diff --git a/volk/kernels/volk/volk_32fc_magnitude_squared_32f.h b/volk/kernels/volk/volk_32fc_magnitude_squared_32f.h
index 878794ba79..ed8eac62d9 100644
--- a/volk/kernels/volk/volk_32fc_magnitude_squared_32f.h
+++ b/volk/kernels/volk/volk_32fc_magnitude_squared_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_magnitude_squared_32f_u_H
#define INCLUDED_volk_32fc_magnitude_squared_32f_u_H
@@ -5,6 +27,50 @@
#include <stdio.h>
#include <math.h>
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+ /*!
+ \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
+ \param complexVector The vector containing the complex input values
+ \param magnitudeVector The vector containing the real output values
+ \param num_points The number of complex values in complexVector to be calculated and stored into cVector
+ */
+static inline void volk_32fc_magnitude_squared_32f_u_avx(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int eighthPoints = num_points / 8;
+
+ const float* complexVectorPtr = (float*)complexVector;
+ float* magnitudeVectorPtr = magnitudeVector;
+
+ __m256 cplxValue1, cplxValue2, complex1, complex2, result;
+ for(;number < eighthPoints; number++){
+ cplxValue1 = _mm256_loadu_ps(complexVectorPtr);
+ complexVectorPtr += 8;
+
+ cplxValue2 = _mm256_loadu_ps(complexVectorPtr);
+ complexVectorPtr += 8;
+
+ cplxValue1 = _mm256_mul_ps(cplxValue1, cplxValue1); // Square the values
+ cplxValue2 = _mm256_mul_ps(cplxValue2, cplxValue2); // Square the Values
+
+ complex1 = _mm256_permute2f128_ps(cplxValue1, cplxValue2, 0x20);
+ complex2 = _mm256_permute2f128_ps(cplxValue1, cplxValue2, 0x31);
+
+ result = _mm256_hadd_ps(complex1, complex2); // Add the I2 and Q2 values
+
+ _mm256_storeu_ps(magnitudeVectorPtr, result);
+ magnitudeVectorPtr += 8;
+ }
+
+ number = eighthPoints * 8;
+ for(; number < num_points; number++){
+ float val1Real = *complexVectorPtr++;
+ float val1Imag = *complexVectorPtr++;
+ *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag);
+ }
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_SSE3
#include <pmmintrin.h>
/*!
@@ -119,6 +185,50 @@ static inline void volk_32fc_magnitude_squared_32f_generic(float* magnitudeVecto
#include <stdio.h>
#include <math.h>
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+ /*!
+ \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
+ \param complexVector The vector containing the complex input values
+ \param magnitudeVector The vector containing the real output values
+ \param num_points The number of complex values in complexVector to be calculated and stored into cVector
+ */
+static inline void volk_32fc_magnitude_squared_32f_a_avx(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int eighthPoints = num_points / 8;
+
+ const float* complexVectorPtr = (float*)complexVector;
+ float* magnitudeVectorPtr = magnitudeVector;
+
+ __m256 cplxValue1, cplxValue2, complex1, complex2, result;
+ for(;number < eighthPoints; number++){
+ cplxValue1 = _mm256_load_ps(complexVectorPtr);
+ complexVectorPtr += 8;
+
+ cplxValue2 = _mm256_load_ps(complexVectorPtr);
+ complexVectorPtr += 8;
+
+ cplxValue1 = _mm256_mul_ps(cplxValue1, cplxValue1); // Square the values
+ cplxValue2 = _mm256_mul_ps(cplxValue2, cplxValue2); // Square the Values
+
+ complex1 = _mm256_permute2f128_ps(cplxValue1, cplxValue2, 0x20);
+ complex2 = _mm256_permute2f128_ps(cplxValue1, cplxValue2, 0x31);
+
+ result = _mm256_hadd_ps(complex1, complex2); // Add the I2 and Q2 values
+
+ _mm256_store_ps(magnitudeVectorPtr, result);
+ magnitudeVectorPtr += 8;
+ }
+
+ number = eighthPoints * 8;
+ for(; number < num_points; number++){
+ float val1Real = *complexVectorPtr++;
+ float val1Imag = *complexVectorPtr++;
+ *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag);
+ }
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_SSE3
#include <pmmintrin.h>
/*!
diff --git a/volk/kernels/volk/volk_32fc_s32f_atan2_32f.h b/volk/kernels/volk/volk_32fc_s32f_atan2_32f.h
index b076ab44ef..2e9221b593 100644
--- a/volk/kernels/volk/volk_32fc_s32f_atan2_32f.h
+++ b/volk/kernels/volk/volk_32fc_s32f_atan2_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_s32f_atan2_32f_a_H
#define INCLUDED_volk_32fc_s32f_atan2_32f_a_H
diff --git a/volk/kernels/volk/volk_32fc_s32f_deinterleave_real_16i.h b/volk/kernels/volk/volk_32fc_s32f_deinterleave_real_16i.h
index 9e10217a0f..0f24512b0e 100644
--- a/volk/kernels/volk/volk_32fc_s32f_deinterleave_real_16i.h
+++ b/volk/kernels/volk/volk_32fc_s32f_deinterleave_real_16i.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_s32f_deinterleave_real_16i_a_H
#define INCLUDED_volk_32fc_s32f_deinterleave_real_16i_a_H
diff --git a/volk/kernels/volk/volk_32fc_s32f_magnitude_16i.h b/volk/kernels/volk/volk_32fc_s32f_magnitude_16i.h
index 09abd967d6..b8ac93a0ec 100644
--- a/volk/kernels/volk/volk_32fc_s32f_magnitude_16i.h
+++ b/volk/kernels/volk/volk_32fc_s32f_magnitude_16i.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_s32f_magnitude_16i_a_H
#define INCLUDED_volk_32fc_s32f_magnitude_16i_a_H
diff --git a/volk/kernels/volk/volk_32fc_s32f_power_32fc.h b/volk/kernels/volk/volk_32fc_s32f_power_32fc.h
index b9dd13baf0..9ecca50d5c 100644
--- a/volk/kernels/volk/volk_32fc_s32f_power_32fc.h
+++ b/volk/kernels/volk/volk_32fc_s32f_power_32fc.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_s32f_power_32fc_a_H
#define INCLUDED_volk_32fc_s32f_power_32fc_a_H
diff --git a/volk/kernels/volk/volk_32fc_s32f_power_spectrum_32f.h b/volk/kernels/volk/volk_32fc_s32f_power_spectrum_32f.h
index f76d9d35e4..8927112344 100644
--- a/volk/kernels/volk/volk_32fc_s32f_power_spectrum_32f.h
+++ b/volk/kernels/volk/volk_32fc_s32f_power_spectrum_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_s32f_power_spectrum_32f_a_H
#define INCLUDED_volk_32fc_s32f_power_spectrum_32f_a_H
diff --git a/volk/kernels/volk/volk_32fc_s32f_x2_power_spectral_density_32f.h b/volk/kernels/volk/volk_32fc_s32f_x2_power_spectral_density_32f.h
index e73eb09f8f..517ade4822 100644
--- a/volk/kernels/volk/volk_32fc_s32f_x2_power_spectral_density_32f.h
+++ b/volk/kernels/volk/volk_32fc_s32f_x2_power_spectral_density_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_s32f_x2_power_spectral_density_32f_a_H
#define INCLUDED_volk_32fc_s32f_x2_power_spectral_density_32f_a_H
@@ -5,6 +27,98 @@
#include <stdio.h>
#include <math.h>
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+
+#ifdef LV_HAVE_LIB_SIMDMATH
+#include <simdmath.h>
+#endif /* LV_HAVE_LIB_SIMDMATH */
+
+/*!
+ \brief Calculates the log10 power value divided by the RBW for each input point
+ \param logPowerOutput The 10.0 * log10((r*r + i*i)/RBW) for each data point
+ \param complexFFTInput The complex data output from the FFT point
+ \param normalizationFactor This value is divided against all the input values before the power is calculated
+ \param rbw The resolution bandwith of the fft spectrum
+ \param num_points The number of fft data points
+*/
+static inline void volk_32fc_s32f_x2_power_spectral_density_32f_a_avx(float* logPowerOutput, const lv_32fc_t* complexFFTInput, const float normalizationFactor, const float rbw, unsigned int num_points){
+ const float* inputPtr = (const float*)complexFFTInput;
+ float* destPtr = logPowerOutput;
+ uint64_t number = 0;
+ const float iRBW = 1.0 / rbw;
+ const float iNormalizationFactor = 1.0 / normalizationFactor;
+
+#ifdef LV_HAVE_LIB_SIMDMATH
+ __m256 magScalar = _mm256_set1_ps(10.0);
+ magScalar = _mm256_div_ps(magScalar, logf4(magScalar));
+
+ __m256 invRBW = _mm256_set1_ps(iRBW);
+
+ __m256 invNormalizationFactor = _mm256_set1_ps(iNormalizationFactor);
+
+ __m256 power;
+ __m256 input1, input2;
+ const uint64_t eighthPoints = num_points / 8;
+ for(;number < eighthPoints; number++){
+ // Load the complex values
+ input1 =_mm256_load_ps(inputPtr);
+ inputPtr += 8;
+ input2 =_mm256_load_ps(inputPtr);
+ inputPtr += 8;
+
+ // Apply the normalization factor
+ input1 = _mm256_mul_ps(input1, invNormalizationFactor);
+ input2 = _mm256_mul_ps(input2, invNormalizationFactor);
+
+ // Multiply each value by itself
+ // (r1*r1), (i1*i1), (r2*r2), (i2*i2)
+ input1 = _mm256_mul_ps(input1, input1);
+ // (r3*r3), (i3*i3), (r4*r4), (i4*i4)
+ input2 = _mm256_mul_ps(input2, input2);
+
+ // Horizontal add, to add (r*r) + (i*i) for each complex value
+ // (r1*r1)+(i1*i1), (r2*r2) + (i2*i2), (r3*r3)+(i3*i3), (r4*r4)+(i4*i4)
+ inputVal1 = _mm256_permute2f128_ps(input1, input2, 0x20);
+ inputVal2 = _mm256_permute2f128_ps(input1, input2, 0x31);
+
+ power = _mm256_hadd_ps(inputVal1, inputVal2);
+
+ // Divide by the rbw
+ power = _mm256_mul_ps(power, invRBW);
+
+ // Calculate the natural log power
+ power = logf4(power);
+
+ // Convert to log10 and multiply by 10.0
+ power = _mm256_mul_ps(power, magScalar);
+
+ // Store the floating point results
+ _mm256_store_ps(destPtr, power);
+
+ destPtr += 8;
+ }
+
+ number = eighthPoints*8;
+#endif /* LV_HAVE_LIB_SIMDMATH */
+ // Calculate the FFT for any remaining points
+ for(; number < num_points; number++){
+ // Calculate dBm
+ // 50 ohm load assumption
+ // 10 * log10 (v^2 / (2 * 50.0 * .001)) = 10 * log10( v^2 * 10)
+ // 75 ohm load assumption
+ // 10 * log10 (v^2 / (2 * 75.0 * .001)) = 10 * log10( v^2 * 15)
+
+ const float real = *inputPtr++ * iNormalizationFactor;
+ const float imag = *inputPtr++ * iNormalizationFactor;
+
+ *destPtr = 10.0*log10f((((real * real) + (imag * imag)) + 1e-20) * iRBW);
+ destPtr++;
+ }
+
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_SSE3
#include <pmmintrin.h>
diff --git a/volk/kernels/volk/volk_32fc_s32fc_multiply_32fc.h b/volk/kernels/volk/volk_32fc_s32fc_multiply_32fc.h
index 668a047609..474b982887 100644
--- a/volk/kernels/volk/volk_32fc_s32fc_multiply_32fc.h
+++ b/volk/kernels/volk/volk_32fc_s32fc_multiply_32fc.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_s32fc_multiply_32fc_u_H
#define INCLUDED_volk_32fc_s32fc_multiply_32fc_u_H
@@ -6,6 +28,52 @@
#include <volk/volk_complex.h>
#include <float.h>
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+ /*!
+ \brief Multiplies the two input complex vectors and stores their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be multiplied
+ \param bVector One of the vectors to be multiplied
+ \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
+ */
+static inline void volk_32fc_s32fc_multiply_32fc_u_avx(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t scalar, unsigned int num_points){
+ unsigned int number = 0;
+ unsigned int i = 0;
+ const unsigned int quarterPoints = num_points / 4;
+ unsigned int isodd = num_points & 3;
+ __m256 x, yl, yh, z, tmp1, tmp2;
+ lv_32fc_t* c = cVector;
+ const lv_32fc_t* a = aVector;
+
+ // Set up constant scalar vector
+ yl = _mm256_set1_ps(lv_creal(scalar));
+ yh = _mm256_set1_ps(lv_cimag(scalar));
+
+ for(;number < quarterPoints; number++){
+ x = _mm256_loadu_ps((float*)a); // Load the ar + ai, br + bi as ar,ai,br,bi
+
+ tmp1 = _mm256_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+
+ x = _mm256_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
+
+ tmp2 = _mm256_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm256_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+
+ _mm256_storeu_ps((float*)c,z); // Store the results back into the C container
+
+ a += 4;
+ c += 4;
+ }
+
+ for(i = num_points-isodd; i < num_points; i++) {
+ *c++ = (*a++) * scalar;
+ }
+
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_SSE3
#include <pmmintrin.h>
/*!
@@ -93,6 +161,52 @@ static inline void volk_32fc_s32fc_multiply_32fc_generic(lv_32fc_t* cVector, con
#include <volk/volk_complex.h>
#include <float.h>
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+ /*!
+ \brief Multiplies the two input complex vectors and stores their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be multiplied
+ \param bVector One of the vectors to be multiplied
+ \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
+ */
+static inline void volk_32fc_s32fc_multiply_32fc_a_avx(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t scalar, unsigned int num_points){
+ unsigned int number = 0;
+ unsigned int i = 0;
+ const unsigned int quarterPoints = num_points / 4;
+ unsigned int isodd = num_points & 3;
+ __m256 x, yl, yh, z, tmp1, tmp2;
+ lv_32fc_t* c = cVector;
+ const lv_32fc_t* a = aVector;
+
+ // Set up constant scalar vector
+ yl = _mm256_set1_ps(lv_creal(scalar));
+ yh = _mm256_set1_ps(lv_cimag(scalar));
+
+ for(;number < quarterPoints; number++){
+ x = _mm256_load_ps((float*)a); // Load the ar + ai, br + bi as ar,ai,br,bi
+
+ tmp1 = _mm256_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+
+ x = _mm256_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
+
+ tmp2 = _mm256_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm256_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+
+ _mm256_store_ps((float*)c,z); // Store the results back into the C container
+
+ a += 4;
+ c += 4;
+ }
+
+ for(i = num_points-isodd; i < num_points; i++) {
+ *c++ = (*a++) * scalar;
+ }
+
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_SSE3
#include <pmmintrin.h>
/*!
@@ -138,6 +252,43 @@ static inline void volk_32fc_s32fc_multiply_32fc_a_sse3(lv_32fc_t* cVector, cons
}
#endif /* LV_HAVE_SSE */
+#ifdef LV_HAVE_NEON
+#include <arm_neon.h>
+ /*!
+ \brief Multiplies the two input complex vectors and stores their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be multiplied
+ \param bVector One of the vectors to be multiplied
+ \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
+ */
+static inline void volk_32fc_s32fc_multiply_32fc_neon(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t scalar, unsigned int num_points){
+ lv_32fc_t* cPtr = cVector;
+ const lv_32fc_t* aPtr = aVector;
+ unsigned int number = num_points;
+ unsigned int quarter_points = num_points / 4;
+
+ float32x4x2_t a_val, scalar_val;
+ float32x4x2_t tmp_imag;
+
+ scalar_val = vld2q_f32((const float*)&scalar);
+ for(number = 0; number < quarter_points; ++number) {
+ a_val = vld2q_f32((float*)aPtr);
+ tmp_imag.val[1] = vmulq_f32(a_val.val[1], scalar_val.val[0]);
+ tmp_imag.val[0] = vmulq_f32(a_val.val[0], scalar_val.val[0]);
+
+ tmp_imag.val[1] = vmlaq_f32(tmp_imag.val[1], a_val.val[0], scalar_val.val[1]);
+ tmp_imag.val[0] = vmlaq_f32(tmp_imag.val[0], a_val.val[1], scalar_val.val[1]);
+
+ vst2q_f32((float*)cVector, tmp_imag);
+ aPtr += 4;
+ cVector += 4;
+ }
+
+ for(number = quarter_points*4; number < num_points; number++){
+ *cPtr++ = *aPtr++ * scalar;
+ }
+}
+#endif /* LV_HAVE_NEON */
#ifdef LV_HAVE_GENERIC
/*!
@@ -171,8 +322,4 @@ static inline void volk_32fc_s32fc_multiply_32fc_a_generic(lv_32fc_t* cVector, c
}
#endif /* LV_HAVE_GENERIC */
-
-
-
-
#endif /* INCLUDED_volk_32fc_x2_multiply_32fc_a_H */
diff --git a/volk/kernels/volk/volk_32fc_s32fc_rotatorpuppet_32fc.h b/volk/kernels/volk/volk_32fc_s32fc_rotatorpuppet_32fc.h
index c7b46e7e99..cbbc43624b 100644
--- a/volk/kernels/volk/volk_32fc_s32fc_rotatorpuppet_32fc.h
+++ b/volk/kernels/volk/volk_32fc_s32fc_rotatorpuppet_32fc.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_s32fc_rotatorpuppet_32fc_a_H
#define INCLUDED_volk_32fc_s32fc_rotatorpuppet_32fc_a_H
diff --git a/volk/kernels/volk/volk_32fc_s32fc_x2_rotator_32fc.h b/volk/kernels/volk/volk_32fc_s32fc_x2_rotator_32fc.h
index 0ed9d67cb5..06500784a1 100644
--- a/volk/kernels/volk/volk_32fc_s32fc_x2_rotator_32fc.h
+++ b/volk/kernels/volk/volk_32fc_s32fc_x2_rotator_32fc.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_s32fc_rotator_32fc_a_H
#define INCLUDED_volk_32fc_s32fc_rotator_32fc_a_H
diff --git a/volk/kernels/volk/volk_32fc_x2_conjugate_dot_prod_32fc.h b/volk/kernels/volk/volk_32fc_x2_conjugate_dot_prod_32fc.h
index e6ccf5c384..8964434bef 100644
--- a/volk/kernels/volk/volk_32fc_x2_conjugate_dot_prod_32fc.h
+++ b/volk/kernels/volk/volk_32fc_x2_conjugate_dot_prod_32fc.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_x2_conjugate_dot_prod_32fc_u_H
#define INCLUDED_volk_32fc_x2_conjugate_dot_prod_32fc_u_H
@@ -142,10 +164,57 @@ static inline void volk_32fc_x2_conjugate_dot_prod_32fc_u_sse3(lv_32fc_t* result
#endif /*LV_HAVE_SSE3*/
+#ifdef LV_HAVE_NEON
+#include <arm_neon.h>
+static inline void volk_32fc_x2_conjugate_dot_prod_32fc_neon(lv_32fc_t* result, const lv_32fc_t* input, const lv_32fc_t* taps, unsigned int num_points) {
+
+ unsigned int quarter_points = num_points / 4;
+ unsigned int number;
+
+ lv_32fc_t* a_ptr = (lv_32fc_t*) taps;
+ lv_32fc_t* b_ptr = (lv_32fc_t*) input;
+ // for 2-lane vectors, 1st lane holds the real part,
+ // 2nd lane holds the imaginary part
+ float32x4x2_t a_val, b_val, accumulator;
+ float32x4x2_t tmp_imag;
+ accumulator.val[0] = vdupq_n_f32(0);
+ accumulator.val[1] = vdupq_n_f32(0);
+
+ for(number = 0; number < quarter_points; ++number) {
+ a_val = vld2q_f32((float*)a_ptr); // a0r|a1r|a2r|a3r || a0i|a1i|a2i|a3i
+ b_val = vld2q_f32((float*)b_ptr); // b0r|b1r|b2r|b3r || b0i|b1i|b2i|b3i
+ __builtin_prefetch(a_ptr+8);
+ __builtin_prefetch(b_ptr+8);
+
+ // do the first multiply
+ tmp_imag.val[1] = vmulq_f32(a_val.val[1], b_val.val[0]);
+ tmp_imag.val[0] = vmulq_f32(a_val.val[0], b_val.val[0]);
+
+ // use multiply accumulate/subtract to get result
+ tmp_imag.val[1] = vmlsq_f32(tmp_imag.val[1], a_val.val[0], b_val.val[1]);
+ tmp_imag.val[0] = vmlaq_f32(tmp_imag.val[0], a_val.val[1], b_val.val[1]);
+
+ accumulator.val[0] = vaddq_f32(accumulator.val[0], tmp_imag.val[0]);
+ accumulator.val[1] = vaddq_f32(accumulator.val[1], tmp_imag.val[1]);
+
+ // increment pointers
+ a_ptr += 4;
+ b_ptr += 4;
+ }
+ lv_32fc_t accum_result[4];
+ vst2q_f32((float*)accum_result, accumulator);
+ *result = accum_result[0] + accum_result[1] + accum_result[2] + accum_result[3];
-#endif /*INCLUDED_volk_32fc_x2_conjugate_dot_prod_32fc_u_H*/
+ // tail case
+ for(number = quarter_points*4; number < num_points; ++number) {
+ *result += (*a_ptr++) * lv_conj(*b_ptr++);
+ }
+ *result = lv_conj(*result);
+}
+#endif /*LV_HAVE_NEON*/
+#endif /*INCLUDED_volk_32fc_x2_conjugate_dot_prod_32fc_u_H*/
#ifndef INCLUDED_volk_32fc_x2_conjugate_dot_prod_32fc_a_H
#define INCLUDED_volk_32fc_x2_conjugate_dot_prod_32fc_a_H
diff --git a/volk/kernels/volk/volk_32fc_x2_dot_prod_32fc.h b/volk/kernels/volk/volk_32fc_x2_dot_prod_32fc.h
index 430b747ff2..c65d0984c5 100644
--- a/volk/kernels/volk/volk_32fc_x2_dot_prod_32fc.h
+++ b/volk/kernels/volk/volk_32fc_x2_dot_prod_32fc.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_x2_dot_prod_32fc_u_H
#define INCLUDED_volk_32fc_x2_dot_prod_32fc_u_H
@@ -316,10 +338,66 @@ static inline void volk_32fc_x2_dot_prod_32fc_u_sse4_1(lv_32fc_t* result, const
#endif /*LV_HAVE_SSE4_1*/
+#ifdef LV_HAVE_AVX
+
+#include <immintrin.h>
+
+static inline void volk_32fc_x2_dot_prod_32fc_u_avx(lv_32fc_t* result, const lv_32fc_t* input, const lv_32fc_t* taps, unsigned int num_points) {
+
+ unsigned int isodd = num_points & 3;
+ unsigned int i = 0;
+ lv_32fc_t dotProduct;
+ memset(&dotProduct, 0x0, 2*sizeof(float));
+
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ __m256 x, y, yl, yh, z, tmp1, tmp2, dotProdVal;
+
+ const lv_32fc_t* a = input;
+ const lv_32fc_t* b = taps;
+
+ dotProdVal = _mm256_setzero_ps();
+
+ for(;number < quarterPoints; number++){
+ x = _mm256_loadu_ps((float*)a); // Load a,b,e,f as ar,ai,br,bi,er,ei,fr,fi
+ y = _mm256_loadu_ps((float*)b); // Load c,d,g,h as cr,ci,dr,di,gr,gi,hr,hi
+
+ yl = _mm256_moveldup_ps(y); // Load yl with cr,cr,dr,dr,gr,gr,hr,hr
+ yh = _mm256_movehdup_ps(y); // Load yh with ci,ci,di,di,gi,gi,hi,hi
+
+ tmp1 = _mm256_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr ...
+
+ x = _mm256_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br,ei,er,fi,fr
+ tmp2 = _mm256_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di ...
+
+ z = _mm256_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+
+ dotProdVal = _mm256_add_ps(dotProdVal, z); // Add the complex multiplication results together
+
+ a += 4;
+ b += 4;
+ }
+
+ __VOLK_ATTR_ALIGNED(32) lv_32fc_t dotProductVector[4];
+
+ _mm256_storeu_ps((float*)dotProductVector,dotProdVal); // Store the results back into the dot product vector
+
+ dotProduct += ( dotProductVector[0] + dotProductVector[1] + dotProductVector[2] + dotProductVector[3]);
+
+ for(i = num_points-isodd; i < num_points; i++) {
+ dotProduct += input[i] * taps[i];
+ }
+
+ *result = dotProduct;
+}
+
+#endif /*LV_HAVE_AVX*/
#endif /*INCLUDED_volk_32fc_x2_dot_prod_32fc_u_H*/
+
#ifndef INCLUDED_volk_32fc_x2_dot_prod_32fc_a_H
#define INCLUDED_volk_32fc_x2_dot_prod_32fc_a_H
@@ -680,6 +758,7 @@ static inline void volk_32fc_x2_dot_prod_32fc_a_sse3(lv_32fc_t* result, const lv
#endif /*LV_HAVE_SSE3*/
+
#ifdef LV_HAVE_SSE4_1
#include <smmintrin.h>
@@ -817,7 +896,7 @@ static inline void volk_32fc_x2_dot_prod_32fc_neon(lv_32fc_t* result, const lv_3
#endif /*LV_HAVE_NEON*/
#ifdef LV_HAVE_NEON
-
+#include <arm_neon.h>
static inline void volk_32fc_x2_dot_prod_32fc_neon_opttests(lv_32fc_t* result, const lv_32fc_t* input, const lv_32fc_t* taps, unsigned int num_points) {
unsigned int quarter_points = num_points / 4;
@@ -976,4 +1055,62 @@ static inline void volk_32fc_x2_dot_prod_32fc_neon_optfmaunroll(lv_32fc_t* resul
#endif /*LV_HAVE_NEON*/
+#ifdef LV_HAVE_AVX
+
+#include <immintrin.h>
+
+static inline void volk_32fc_x2_dot_prod_32fc_a_avx(lv_32fc_t* result, const lv_32fc_t* input, const lv_32fc_t* taps, unsigned int num_points) {
+
+ unsigned int isodd = num_points & 3;
+ unsigned int i = 0;
+ lv_32fc_t dotProduct;
+ memset(&dotProduct, 0x0, 2*sizeof(float));
+
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ __m256 x, y, yl, yh, z, tmp1, tmp2, dotProdVal;
+
+ const lv_32fc_t* a = input;
+ const lv_32fc_t* b = taps;
+
+ dotProdVal = _mm256_setzero_ps();
+
+ for(;number < quarterPoints; number++){
+
+ x = _mm256_load_ps((float*)a); // Load a,b,e,f as ar,ai,br,bi,er,ei,fr,fi
+ y = _mm256_load_ps((float*)b); // Load c,d,g,h as cr,ci,dr,di,gr,gi,hr,hi
+
+ yl = _mm256_moveldup_ps(y); // Load yl with cr,cr,dr,dr,gr,gr,hr,hr
+ yh = _mm256_movehdup_ps(y); // Load yh with ci,ci,di,di,gi,gi,hi,hi
+
+ tmp1 = _mm256_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr ...
+
+ x = _mm256_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br,ei,er,fi,fr
+
+ tmp2 = _mm256_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di ...
+
+ z = _mm256_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+
+ dotProdVal = _mm256_add_ps(dotProdVal, z); // Add the complex multiplication results together
+
+ a += 4;
+ b += 4;
+ }
+
+ __VOLK_ATTR_ALIGNED(32) lv_32fc_t dotProductVector[4];
+
+ _mm256_store_ps((float*)dotProductVector,dotProdVal); // Store the results back into the dot product vector
+
+ dotProduct += ( dotProductVector[0] + dotProductVector[1] + dotProductVector[2] + dotProductVector[3]);
+
+ for(i = num_points-isodd; i < num_points; i++) {
+ dotProduct += input[i] * taps[i];
+ }
+
+ *result = dotProduct;
+}
+
+#endif /*LV_HAVE_AVX*/
+
#endif /*INCLUDED_volk_32fc_x2_dot_prod_32fc_a_H*/
diff --git a/volk/kernels/volk/volk_32fc_x2_multiply_32fc.h b/volk/kernels/volk/volk_32fc_x2_multiply_32fc.h
index 7c723bcdb6..4575439e94 100644
--- a/volk/kernels/volk/volk_32fc_x2_multiply_32fc.h
+++ b/volk/kernels/volk/volk_32fc_x2_multiply_32fc.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_x2_multiply_32fc_u_H
#define INCLUDED_volk_32fc_x2_multiply_32fc_u_H
@@ -6,6 +28,55 @@
#include <volk/volk_complex.h>
#include <float.h>
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+ /*!
+ \brief Multiplies the two input complex vectors and stores their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be multiplied
+ \param bVector One of the vectors to be multiplied
+ \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
+ */
+static inline void volk_32fc_x2_multiply_32fc_u_avx(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t* bVector, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ __m256 x, y, yl, yh, z, tmp1, tmp2;
+ lv_32fc_t* c = cVector;
+ const lv_32fc_t* a = aVector;
+ const lv_32fc_t* b = bVector;
+
+ for(;number < quarterPoints; number++){
+
+ x = _mm256_loadu_ps((float*)a); // Load the ar + ai, br + bi ... as ar,ai,br,bi ...
+ y = _mm256_loadu_ps((float*)b); // Load the cr + ci, dr + di ... as cr,ci,dr,di ...
+
+ yl = _mm256_moveldup_ps(y); // Load yl with cr,cr,dr,dr ...
+ yh = _mm256_movehdup_ps(y); // Load yh with ci,ci,di,di ...
+
+ tmp1 = _mm256_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr ...
+
+ x = _mm256_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br ...
+
+ tmp2 = _mm256_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm256_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+
+ _mm256_storeu_ps((float*)c,z); // Store the results back into the C container
+
+ a += 4;
+ b += 4;
+ c += 4;
+ }
+
+ number = quarterPoints * 4;
+
+ for(; number < num_points; number++) {
+ *c++ = (*a++) * (*b++);
+ }
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_SSE3
#include <pmmintrin.h>
/*!
@@ -83,6 +154,55 @@ static inline void volk_32fc_x2_multiply_32fc_generic(lv_32fc_t* cVector, const
#include <volk/volk_complex.h>
#include <float.h>
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+ /*!
+ \brief Multiplies the two input complex vectors and stores their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be multiplied
+ \param bVector One of the vectors to be multiplied
+ \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
+ */
+static inline void volk_32fc_x2_multiply_32fc_a_avx(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t* bVector, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ __m256 x, y, yl, yh, z, tmp1, tmp2;
+ lv_32fc_t* c = cVector;
+ const lv_32fc_t* a = aVector;
+ const lv_32fc_t* b = bVector;
+
+ for(;number < quarterPoints; number++){
+
+ x = _mm256_load_ps((float*)a); // Load the ar + ai, br + bi ... as ar,ai,br,bi ...
+ y = _mm256_load_ps((float*)b); // Load the cr + ci, dr + di ... as cr,ci,dr,di ...
+
+ yl = _mm256_moveldup_ps(y); // Load yl with cr,cr,dr,dr ...
+ yh = _mm256_movehdup_ps(y); // Load yh with ci,ci,di,di ...
+
+ tmp1 = _mm256_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr ...
+
+ x = _mm256_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br ...
+
+ tmp2 = _mm256_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm256_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+
+ _mm256_store_ps((float*)c,z); // Store the results back into the C container
+
+ a += 4;
+ b += 4;
+ c += 4;
+ }
+
+ number = quarterPoints * 4;
+
+ for(; number < num_points; number++) {
+ *c++ = (*a++) * (*b++);
+ }
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_SSE3
#include <pmmintrin.h>
/*!
diff --git a/volk/kernels/volk/volk_32fc_x2_multiply_conjugate_32fc.h b/volk/kernels/volk/volk_32fc_x2_multiply_conjugate_32fc.h
index dbc123ff25..c9b3bbc70b 100644
--- a/volk/kernels/volk/volk_32fc_x2_multiply_conjugate_32fc.h
+++ b/volk/kernels/volk/volk_32fc_x2_multiply_conjugate_32fc.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_x2_multiply_conjugate_32fc_u_H
#define INCLUDED_volk_32fc_x2_multiply_conjugate_32fc_u_H
@@ -6,6 +28,59 @@
#include <volk/volk_complex.h>
#include <float.h>
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+ /*!
+ \brief Multiplies vector a by the conjugate of vector b and stores the results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector First vector to be multiplied
+ \param bVector Second vector that is conjugated before being multiplied
+ \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
+ */
+static inline void volk_32fc_x2_multiply_conjugate_32fc_u_avx(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t* bVector, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ __m256 x, y, yl, yh, z, tmp1, tmp2;
+ lv_32fc_t* c = cVector;
+ const lv_32fc_t* a = aVector;
+ const lv_32fc_t* b = bVector;
+
+ __m256 conjugator = _mm256_setr_ps(0, -0.f, 0, -0.f, 0, -0.f, 0, -0.f);
+
+ for(;number < quarterPoints; number++){
+
+ x = _mm256_loadu_ps((float*)a); // Load the ar + ai, br + bi ... as ar,ai,br,bi ...
+ y = _mm256_loadu_ps((float*)b); // Load the cr + ci, dr + di ... as cr,ci,dr,di ...
+
+ y = _mm256_xor_ps(y, conjugator); // conjugate y
+
+ yl = _mm256_moveldup_ps(y); // Load yl with cr,cr,dr,dr ...
+ yh = _mm256_movehdup_ps(y); // Load yh with ci,ci,di,di ...
+
+ tmp1 = _mm256_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr ...
+
+ x = _mm256_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br ...
+
+ tmp2 = _mm256_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di ...
+
+ z = _mm256_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di ...
+
+ _mm256_storeu_ps((float*)c,z); // Store the results back into the C container
+
+ a += 4;
+ b += 4;
+ c += 4;
+ }
+
+ number = quarterPoints * 4;
+
+ for(; number < num_points; number++) {
+ *c++ = (*a++) * lv_conj(*b++);
+ }
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_SSE3
#include <pmmintrin.h>
/*!
@@ -87,6 +162,59 @@ static inline void volk_32fc_x2_multiply_conjugate_32fc_generic(lv_32fc_t* cVect
#include <volk/volk_complex.h>
#include <float.h>
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+ /*!
+ \brief Multiplies vector a by the conjugate of vector b and stores the results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector First vector to be multiplied
+ \param bVector Second vector that is conjugated before being multiplied
+ \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
+ */
+static inline void volk_32fc_x2_multiply_conjugate_32fc_a_avx(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t* bVector, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ __m256 x, y, yl, yh, z, tmp1, tmp2;
+ lv_32fc_t* c = cVector;
+ const lv_32fc_t* a = aVector;
+ const lv_32fc_t* b = bVector;
+
+ __m256 conjugator = _mm256_setr_ps(0, -0.f, 0, -0.f, 0, -0.f, 0, -0.f);
+
+ for(;number < quarterPoints; number++){
+
+ x = _mm256_load_ps((float*)a); // Load the ar + ai, br + bi ... as ar,ai,br,bi ...
+ y = _mm256_load_ps((float*)b); // Load the cr + ci, dr + di ... as cr,ci,dr,di ...
+
+ y = _mm256_xor_ps(y, conjugator); // conjugate y
+
+ yl = _mm256_moveldup_ps(y); // Load yl with cr,cr,dr,dr ...
+ yh = _mm256_movehdup_ps(y); // Load yh with ci,ci,di,di ...
+
+ tmp1 = _mm256_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr ...
+
+ x = _mm256_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br ...
+
+ tmp2 = _mm256_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di ...
+
+ z = _mm256_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di ...
+
+ _mm256_store_ps((float*)c,z); // Store the results back into the C container
+
+ a += 4;
+ b += 4;
+ c += 4;
+ }
+
+ number = quarterPoints * 4;
+
+ for(; number < num_points; number++) {
+ *c++ = (*a++) * lv_conj(*b++);
+ }
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_SSE3
#include <pmmintrin.h>
/*!
diff --git a/volk/kernels/volk/volk_32fc_x2_s32f_square_dist_scalar_mult_32f.h b/volk/kernels/volk/volk_32fc_x2_s32f_square_dist_scalar_mult_32f.h
index cb2e945015..a25a6866b7 100644
--- a/volk/kernels/volk/volk_32fc_x2_s32f_square_dist_scalar_mult_32f.h
+++ b/volk/kernels/volk/volk_32fc_x2_s32f_square_dist_scalar_mult_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_x2_s32f_square_dist_scalar_mult_32f_a_H
#define INCLUDED_volk_32fc_x2_s32f_square_dist_scalar_mult_32f_a_H
diff --git a/volk/kernels/volk/volk_32fc_x2_square_dist_32f.h b/volk/kernels/volk/volk_32fc_x2_square_dist_32f.h
index 56b3d5c230..2984beaa17 100644
--- a/volk/kernels/volk/volk_32fc_x2_square_dist_32f.h
+++ b/volk/kernels/volk/volk_32fc_x2_square_dist_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32fc_x2_square_dist_32f_a_H
#define INCLUDED_volk_32fc_x2_square_dist_32f_a_H
diff --git a/volk/kernels/volk/volk_32i_s32f_convert_32f.h b/volk/kernels/volk/volk_32i_s32f_convert_32f.h
index 7a09883453..dd965bc9b2 100644
--- a/volk/kernels/volk/volk_32i_s32f_convert_32f.h
+++ b/volk/kernels/volk/volk_32i_s32f_convert_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32i_s32f_convert_32f_u_H
#define INCLUDED_volk_32i_s32f_convert_32f_u_H
diff --git a/volk/kernels/volk/volk_32i_x2_and_32i.h b/volk/kernels/volk/volk_32i_x2_and_32i.h
index 54ecb79812..c138540e69 100644
--- a/volk/kernels/volk/volk_32i_x2_and_32i.h
+++ b/volk/kernels/volk/volk_32i_x2_and_32i.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32i_x2_and_32i_a_H
#define INCLUDED_volk_32i_x2_and_32i_a_H
@@ -43,6 +65,40 @@ static inline void volk_32i_x2_and_32i_a_sse(int32_t* cVector, const int32_t* aV
}
#endif /* LV_HAVE_SSE */
+#ifdef LV_HAVE_NEON
+#include <arm_neon.h>
+/*!
+ \brief Ands the two input vectors and store their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors
+ \param bVector One of the vectors
+ \param num_points The number of values in aVector and bVector to be anded together and stored into cVector
+*/
+static inline void volk_32i_x2_and_32i_neon(int32_t* cVector, const int32_t* aVector, const int32_t* bVector, unsigned int num_points){
+ int32_t* cPtr = cVector;
+ const int32_t* aPtr = aVector;
+ const int32_t* bPtr= bVector;
+ unsigned int number = 0;
+ unsigned int quarter_points = num_points / 4;
+
+ int32x4_t a_val, b_val, c_val;
+
+ for(number = 0; number < quarter_points; number++){
+ a_val = vld1q_s32(aPtr);
+ b_val = vld1q_s32(bPtr);
+ c_val = vandq_s32(a_val, b_val);
+ vst1q_s32(cPtr, c_val);
+ aPtr += 4;
+ bPtr += 4;
+ cPtr += 4;
+ }
+
+ for(number = quarter_points * 4; number < num_points; number++){
+ *cPtr++ = (*aPtr++) & (*bPtr++);
+ }
+}
+#endif /* LV_HAVE_NEON */
+
#ifdef LV_HAVE_GENERIC
/*!
\brief Ands the two input vectors and store their results in the third vector
diff --git a/volk/kernels/volk/volk_32i_x2_or_32i.h b/volk/kernels/volk/volk_32i_x2_or_32i.h
index acadd5a57f..544a71c67c 100644
--- a/volk/kernels/volk/volk_32i_x2_or_32i.h
+++ b/volk/kernels/volk/volk_32i_x2_or_32i.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32i_x2_or_32i_a_H
#define INCLUDED_volk_32i_x2_or_32i_a_H
@@ -43,6 +65,40 @@ static inline void volk_32i_x2_or_32i_a_sse(int32_t* cVector, const int32_t* aVe
}
#endif /* LV_HAVE_SSE */
+#ifdef LV_HAVE_NEON
+#include <arm_neon.h>
+/*!
+ \brief Ands the two input vectors and store their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors
+ \param bVector One of the vectors
+ \param num_points The number of values in aVector and bVector to be anded together and stored into cVector
+*/
+static inline void volk_32i_x2_or_32i_neon(int32_t* cVector, const int32_t* aVector, const int32_t* bVector, unsigned int num_points){
+ int32_t* cPtr = cVector;
+ const int32_t* aPtr = aVector;
+ const int32_t* bPtr= bVector;
+ unsigned int number = 0;
+ unsigned int quarter_points = num_points / 4;
+
+ int32x4_t a_val, b_val, c_val;
+
+ for(number = 0; number < quarter_points; number++){
+ a_val = vld1q_s32(aPtr);
+ b_val = vld1q_s32(bPtr);
+ c_val = vorrq_s32(a_val, b_val);
+ vst1q_s32(cPtr, c_val);
+ aPtr += 4;
+ bPtr += 4;
+ cPtr += 4;
+ }
+
+ for(number = quarter_points * 4; number < num_points; number++){
+ *cPtr++ = (*aPtr++) | (*bPtr++);
+ }
+}
+#endif /* LV_HAVE_NEON */
+
#ifdef LV_HAVE_GENERIC
/*!
\brief Ors the two input vectors and store their results in the third vector
diff --git a/volk/kernels/volk/volk_32u_byteswap.h b/volk/kernels/volk/volk_32u_byteswap.h
index 8f6e3ad7b5..0194efc12c 100644
--- a/volk/kernels/volk/volk_32u_byteswap.h
+++ b/volk/kernels/volk/volk_32u_byteswap.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_32u_byteswap_u_H
#define INCLUDED_volk_32u_byteswap_u_H
@@ -51,6 +73,59 @@ static inline void volk_32u_byteswap_u_sse2(uint32_t* intsToSwap, unsigned int n
}
#endif /* LV_HAVE_SSE2 */
+#ifdef LV_HAVE_NEON
+#include <arm_neon.h>
+/*!
+ \brief Byteswaps (in-place) an aligned vector of int32_t's.
+ \param intsToSwap The vector of data to byte swap
+ \param numDataPoints The number of data points
+*/
+static inline void volk_32u_byteswap_neon(uint32_t* intsToSwap, unsigned int num_points){
+ uint32_t* inputPtr = intsToSwap;
+ unsigned int number = 0;
+ unsigned int n8points = num_points / 8;
+
+ uint8x8x4_t input_table;
+ uint8x8_t int_lookup01, int_lookup23, int_lookup45, int_lookup67;
+ uint8x8_t swapped_int01, swapped_int23, swapped_int45, swapped_int67;
+
+ /* these magic numbers are used as byte-indeces in the LUT.
+ they are pre-computed to save time. A simple C program
+ can calculate them; for example for lookup01:
+ uint8_t chars[8] = {24, 16, 8, 0, 25, 17, 9, 1};
+ for(ii=0; ii < 8; ++ii) {
+ index += ((uint64_t)(*(chars+ii))) << (ii*8);
+ }
+ */
+ int_lookup01 = vcreate_u8(74609667900706840);
+ int_lookup23 = vcreate_u8(219290013576860186);
+ int_lookup45 = vcreate_u8(363970359253013532);
+ int_lookup67 = vcreate_u8(508650704929166878);
+
+ for(number = 0; number < n8points; ++number){
+ input_table = vld4_u8((uint8_t*) inputPtr);
+ swapped_int01 = vtbl4_u8(input_table, int_lookup01);
+ swapped_int23 = vtbl4_u8(input_table, int_lookup23);
+ swapped_int45 = vtbl4_u8(input_table, int_lookup45);
+ swapped_int67 = vtbl4_u8(input_table, int_lookup67);
+ vst1_u8((uint8_t*) inputPtr, swapped_int01);
+ vst1_u8((uint8_t*) (inputPtr+2), swapped_int23);
+ vst1_u8((uint8_t*) (inputPtr+4), swapped_int45);
+ vst1_u8((uint8_t*) (inputPtr+6), swapped_int67);
+
+ inputPtr += 8;
+ }
+
+ for(number = n8points * 8; number < num_points; ++number){
+ uint32_t output = *inputPtr;
+ output = (((output >> 24) & 0xff) | ((output >> 8) & 0x0000ff00) | ((output << 8) & 0x00ff0000) | ((output << 24) & 0xff000000));
+
+ *inputPtr = output;
+ inputPtr++;
+ }
+}
+#endif /* LV_HAVE_NEON */
+
#ifdef LV_HAVE_GENERIC
/*!
\brief Byteswaps (in-place) an aligned vector of int32_t's.
@@ -72,8 +147,6 @@ static inline void volk_32u_byteswap_generic(uint32_t* intsToSwap, unsigned int
#endif /* LV_HAVE_GENERIC */
-
-
#endif /* INCLUDED_volk_32u_byteswap_u_H */
#ifndef INCLUDED_volk_32u_byteswap_a_H
#define INCLUDED_volk_32u_byteswap_a_H
diff --git a/volk/kernels/volk/volk_32u_byteswappuppet_32u.h b/volk/kernels/volk/volk_32u_byteswappuppet_32u.h
new file mode 100644
index 0000000000..bf7055e241
--- /dev/null
+++ b/volk/kernels/volk/volk_32u_byteswappuppet_32u.h
@@ -0,0 +1,45 @@
+#ifndef INCLUDED_volk_32u_byteswappuppet_32u_H
+#define INCLUDED_volk_32u_byteswappuppet_32u_H
+
+
+#include <stdint.h>
+#include <volk/volk_32u_byteswap.h>
+
+#ifdef LV_HAVE_GENERIC
+static inline void volk_32u_byteswappuppet_32u_generic(uint32_t*output, uint32_t* intsToSwap, unsigned int num_points){
+
+ volk_32u_byteswap_generic((uint32_t*)intsToSwap, num_points);
+ memcpy((void*)output, (void*)intsToSwap, num_points * sizeof(uint32_t));
+
+}
+#endif
+
+#ifdef LV_HAVE_NEON
+static inline void volk_32u_byteswappuppet_32u_neon(uint32_t*output, uint32_t* intsToSwap, unsigned int num_points){
+
+ volk_32u_byteswap_neon((uint32_t*)intsToSwap, num_points);
+ memcpy((void*)output, (void*)intsToSwap, num_points * sizeof(uint32_t));
+
+}
+#endif
+
+#ifdef LV_HAVE_SSE2
+static inline void volk_32u_byteswappuppet_32u_u_sse2(uint32_t *output, uint32_t* intsToSwap, unsigned int num_points){
+
+ volk_32u_byteswap_u_sse2((uint32_t*)intsToSwap, num_points);
+ memcpy((void*)output, (void*)intsToSwap, num_points * sizeof(uint32_t));
+
+}
+#endif
+
+#ifdef LV_HAVE_SSE2
+static inline void volk_32u_byteswappuppet_32u_a_sse2(uint32_t* output, uint32_t* intsToSwap, unsigned int num_points){
+
+ volk_32u_byteswap_a_sse2((uint32_t*)intsToSwap, num_points);
+ memcpy((void*)output, (void*)intsToSwap, num_points * sizeof(uint32_t));
+
+}
+#endif
+
+
+#endif
diff --git a/volk/kernels/volk/volk_32u_popcnt.h b/volk/kernels/volk/volk_32u_popcnt.h
index 9783569729..8d613754df 100644
--- a/volk/kernels/volk/volk_32u_popcnt.h
+++ b/volk/kernels/volk/volk_32u_popcnt.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_VOLK_32u_POPCNT_A16_H
#define INCLUDED_VOLK_32u_POPCNT_A16_H
diff --git a/volk/kernels/volk/volk_32u_popcntpuppet_32u.h b/volk/kernels/volk/volk_32u_popcntpuppet_32u.h
new file mode 100644
index 0000000000..056983e817
--- /dev/null
+++ b/volk/kernels/volk/volk_32u_popcntpuppet_32u.h
@@ -0,0 +1,47 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_volk_32u_popcntpuppet_32u_H
+#define INCLUDED_volk_32u_popcntpuppet_32u_H
+
+#include <stdint.h>
+#include <volk/volk_32u_popcnt.h>
+
+#ifdef LV_HAVE_GENERIC
+static inline void volk_32u_popcntpuppet_32u_generic(uint32_t* outVector, const uint32_t* inVector, unsigned int num_points){
+ unsigned int ii;
+ for(ii=0; ii < num_points; ++ii) {
+ volk_32u_popcnt_generic(outVector+ii, *(inVector+ii) );
+ }
+}
+#endif /* LV_HAVE_GENERIC */
+
+#ifdef LV_HAVE_SSE_4_2
+static inline void volk_32u_popcntpuppet_32u_a_sse4_2(uint32_t* outVector, const uint32_t* inVector, unsigned int num_points){
+ unsigned int ii;
+ for(ii=0; ii < num_points; ++ii) {
+ volk_32u_popcnt_a_sse4_2(outVector+ii, *(inVector+ii) );
+ }
+}
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_volk_32fc_s32fc_rotatorpuppet_32fc_a_H */
diff --git a/volk/kernels/volk/volk_64f_convert_32f.h b/volk/kernels/volk/volk_64f_convert_32f.h
index c27526ffaf..39a7ae8fd0 100644
--- a/volk/kernels/volk/volk_64f_convert_32f.h
+++ b/volk/kernels/volk/volk_64f_convert_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_64f_convert_32f_u_H
#define INCLUDED_volk_64f_convert_32f_u_H
diff --git a/volk/kernels/volk/volk_64f_x2_max_64f.h b/volk/kernels/volk/volk_64f_x2_max_64f.h
index f9a04c2c40..7bf09e8514 100644
--- a/volk/kernels/volk/volk_64f_x2_max_64f.h
+++ b/volk/kernels/volk/volk_64f_x2_max_64f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_64f_x2_max_64f_a_H
#define INCLUDED_volk_64f_x2_max_64f_a_H
diff --git a/volk/kernels/volk/volk_64f_x2_min_64f.h b/volk/kernels/volk/volk_64f_x2_min_64f.h
index c77ca87fbd..8d8b377503 100644
--- a/volk/kernels/volk/volk_64f_x2_min_64f.h
+++ b/volk/kernels/volk/volk_64f_x2_min_64f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_64f_x2_min_64f_a_H
#define INCLUDED_volk_64f_x2_min_64f_a_H
diff --git a/volk/kernels/volk/volk_64u_byteswap.h b/volk/kernels/volk/volk_64u_byteswap.h
index e05daf6d5c..dce883278d 100644
--- a/volk/kernels/volk/volk_64u_byteswap.h
+++ b/volk/kernels/volk/volk_64u_byteswap.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_64u_byteswap_u_H
#define INCLUDED_volk_64u_byteswap_u_H
@@ -82,7 +104,62 @@ static inline void volk_64u_byteswap_generic(uint64_t* intsToSwap, unsigned int
}
#endif /* LV_HAVE_GENERIC */
+#ifdef LV_HAVE_NEON
+#include <arm_neon.h>
+/*!
+ \brief Byteswaps (in-place) a vector of int64_t's.
+ \param intsToSwap The vector of data to byte swap
+ \param numDataPoints The number of data points
+*/
+static inline void volk_64u_byteswap_neon(uint64_t* intsToSwap, unsigned int num_points){
+ uint32_t* inputPtr = (uint32_t*)intsToSwap;
+ unsigned int number = 0;
+ unsigned int n8points = num_points / 4;
+
+ uint8x8x4_t input_table;
+ uint8x8_t int_lookup01, int_lookup23, int_lookup45, int_lookup67;
+ uint8x8_t swapped_int01, swapped_int23, swapped_int45, swapped_int67;
+
+ /* these magic numbers are used as byte-indeces in the LUT.
+ they are pre-computed to save time. A simple C program
+ can calculate them; for example for lookup01:
+ uint8_t chars[8] = {24, 16, 8, 0, 25, 17, 9, 1};
+ for(ii=0; ii < 8; ++ii) {
+ index += ((uint64_t)(*(chars+ii))) << (ii*8);
+ }
+ */
+ int_lookup01 = vcreate_u8(2269495096316185);
+ int_lookup23 = vcreate_u8(146949840772469531);
+ int_lookup45 = vcreate_u8(291630186448622877);
+ int_lookup67 = vcreate_u8(436310532124776223);
+
+ for(number = 0; number < n8points; ++number){
+ input_table = vld4_u8((uint8_t*) inputPtr);
+ swapped_int01 = vtbl4_u8(input_table, int_lookup01);
+ swapped_int23 = vtbl4_u8(input_table, int_lookup23);
+ swapped_int45 = vtbl4_u8(input_table, int_lookup45);
+ swapped_int67 = vtbl4_u8(input_table, int_lookup67);
+ vst1_u8((uint8_t*) inputPtr, swapped_int01);
+ vst1_u8((uint8_t*) (inputPtr+2), swapped_int23);
+ vst1_u8((uint8_t*) (inputPtr+4), swapped_int45);
+ vst1_u8((uint8_t*) (inputPtr+6), swapped_int67);
+
+ inputPtr += 4;
+ }
+ for(number = n8points * 4; number < num_points; ++number){
+ uint32_t output1 = *inputPtr;
+ uint32_t output2 = inputPtr[1];
+
+ output1 = (((output1 >> 24) & 0xff) | ((output1 >> 8) & 0x0000ff00) | ((output1 << 8) & 0x00ff0000) | ((output1 << 24) & 0xff000000));
+ output2 = (((output2 >> 24) & 0xff) | ((output2 >> 8) & 0x0000ff00) | ((output2 << 8) & 0x00ff0000) | ((output2 << 24) & 0xff000000));
+
+ *inputPtr++ = output2;
+ *inputPtr++ = output1;
+ }
+
+}
+#endif /* LV_HAVE_NEON */
#endif /* INCLUDED_volk_64u_byteswap_u_H */
diff --git a/volk/kernels/volk/volk_64u_byteswappuppet_64u.h b/volk/kernels/volk/volk_64u_byteswappuppet_64u.h
new file mode 100644
index 0000000000..ac5b16e212
--- /dev/null
+++ b/volk/kernels/volk/volk_64u_byteswappuppet_64u.h
@@ -0,0 +1,45 @@
+#ifndef INCLUDED_volk_64u_byteswappuppet_64u_H
+#define INCLUDED_volk_64u_byteswappuppet_64u_H
+
+
+#include <stdint.h>
+#include <volk/volk_64u_byteswap.h>
+
+#ifdef LV_HAVE_GENERIC
+static inline void volk_64u_byteswappuppet_64u_generic(uint64_t*output, uint64_t* intsToSwap, unsigned int num_points){
+
+ volk_64u_byteswap_generic((uint64_t*)intsToSwap, num_points);
+ memcpy((void*)output, (void*)intsToSwap, num_points * sizeof(uint64_t));
+
+}
+#endif
+
+#ifdef LV_HAVE_NEON
+static inline void volk_64u_byteswappuppet_64u_neon(uint64_t*output, uint64_t* intsToSwap, unsigned int num_points){
+
+ volk_64u_byteswap_neon((uint64_t*)intsToSwap, num_points);
+ memcpy((void*)output, (void*)intsToSwap, num_points * sizeof(uint64_t));
+
+}
+#endif
+
+#ifdef LV_HAVE_SSE2
+static inline void volk_64u_byteswappuppet_64u_u_sse2(uint64_t* output, uint64_t* intsToSwap, unsigned int num_points){
+
+ volk_64u_byteswap_u_sse2((uint64_t*)intsToSwap, num_points);
+ memcpy((void*)output, (void*)intsToSwap, num_points * sizeof(uint64_t));
+
+}
+#endif
+
+#ifdef LV_HAVE_SSE2
+static inline void volk_64u_byteswappuppet_64u_a_sse2(uint64_t* output, uint64_t* intsToSwap, unsigned int num_points){
+
+ volk_64u_byteswap_a_sse2((uint64_t*)intsToSwap, num_points);
+ memcpy((void*)output, (void*)intsToSwap, num_points * sizeof(uint64_t));
+
+}
+#endif
+
+
+#endif
diff --git a/volk/kernels/volk/volk_64u_popcnt.h b/volk/kernels/volk/volk_64u_popcnt.h
index 466cfa5dad..0ec72e3404 100644
--- a/volk/kernels/volk/volk_64u_popcnt.h
+++ b/volk/kernels/volk/volk_64u_popcnt.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_64u_popcnt_a_H
#define INCLUDED_volk_64u_popcnt_a_H
@@ -49,4 +71,24 @@ static inline void volk_64u_popcnt_a_sse4_2(uint64_t* ret, const uint64_t value)
#endif /*LV_HAVE_SSE4_2*/
+#if LV_HAVE_NEON
+#include <arm_neon.h>
+static inline void volk_64u_popcnt_neon(uint64_t* ret, const uint64_t value) {
+ uint8x8_t input_val, count8x8_val;
+ uint16x4_t count16x4_val;
+ uint32x2_t count32x2_val;
+ uint64x1_t count64x1_val;
+
+ input_val = vld1_u8((unsigned char *) &value);
+ count8x8_val = vcnt_u8(input_val);
+ count16x4_val = vpaddl_u8(count8x8_val);
+ count32x2_val = vpaddl_u16(count16x4_val);
+ count64x1_val = vpaddl_u32(count32x2_val);
+ vst1_u64(ret, count64x1_val);
+
+ //*ret = _mm_popcnt_u64(value);
+
+}
+#endif /*LV_HAVE_NEON*/
+
#endif /*INCLUDED_volk_64u_popcnt_a_H*/
diff --git a/volk/kernels/volk/volk_64u_popcntpuppet_64u.h b/volk/kernels/volk/volk_64u_popcntpuppet_64u.h
new file mode 100644
index 0000000000..3903e0d561
--- /dev/null
+++ b/volk/kernels/volk/volk_64u_popcntpuppet_64u.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_volk_64u_popcntpuppet_64u_H
+#define INCLUDED_volk_64u_popcntpuppet_64u_H
+
+#include <stdint.h>
+#include <volk/volk_64u_popcnt.h>
+
+#ifdef LV_HAVE_GENERIC
+static inline void volk_64u_popcntpuppet_64u_generic(uint64_t* outVector, const uint64_t* inVector, unsigned int num_points){
+ unsigned int ii;
+ for(ii=0; ii < num_points; ++ii) {
+ volk_64u_popcnt_generic(outVector+ii, num_points );
+
+ }
+}
+#endif /* LV_HAVE_GENERIC */
+
+#ifdef LV_HAVE_NEON
+static inline void volk_64u_popcntpuppet_64u_neon(uint64_t* outVector, const uint64_t* inVector, unsigned int num_points){
+ unsigned int ii;
+ for(ii=0; ii < num_points; ++ii) {
+ volk_64u_popcnt_neon(outVector+ii, num_points );
+ }
+}
+#endif /* LV_HAVE_NEON */
+
+#endif /* INCLUDED_volk_32fc_s32fc_rotatorpuppet_32fc_a_H */
diff --git a/volk/kernels/volk/volk_8i_convert_16i.h b/volk/kernels/volk/volk_8i_convert_16i.h
index 9776dfdc66..549ba4e388 100644
--- a/volk/kernels/volk/volk_8i_convert_16i.h
+++ b/volk/kernels/volk/volk_8i_convert_16i.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_8i_convert_16i_u_H
#define INCLUDED_volk_8i_convert_16i_u_H
diff --git a/volk/kernels/volk/volk_8i_s32f_convert_32f.h b/volk/kernels/volk/volk_8i_s32f_convert_32f.h
index bd7ff82d9a..5e959c8692 100644
--- a/volk/kernels/volk/volk_8i_s32f_convert_32f.h
+++ b/volk/kernels/volk/volk_8i_s32f_convert_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_8i_s32f_convert_32f_u_H
#define INCLUDED_volk_8i_s32f_convert_32f_u_H
diff --git a/volk/kernels/volk/volk_8ic_deinterleave_16i_x2.h b/volk/kernels/volk/volk_8ic_deinterleave_16i_x2.h
index b59d22d186..818d309013 100644
--- a/volk/kernels/volk/volk_8ic_deinterleave_16i_x2.h
+++ b/volk/kernels/volk/volk_8ic_deinterleave_16i_x2.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_8ic_deinterleave_16i_x2_a_H
#define INCLUDED_volk_8ic_deinterleave_16i_x2_a_H
@@ -13,30 +35,31 @@
\param qBuffer The Q buffer output data
\param num_points The number of complex data values to be deinterleaved
*/
+
static inline void volk_8ic_deinterleave_16i_x2_a_sse4_1(int16_t* iBuffer, int16_t* qBuffer, const lv_8sc_t* complexVector, unsigned int num_points){
unsigned int number = 0;
const int8_t* complexVectorPtr = (int8_t*)complexVector;
int16_t* iBufferPtr = iBuffer;
int16_t* qBufferPtr = qBuffer;
- __m128i iMoveMask = _mm_set_epi8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 14, 12, 10, 8, 6, 4, 2, 0);
+ __m128i iMoveMask = _mm_set_epi8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 14, 12, 10, 8, 6, 4, 2, 0); // set 16 byte values
__m128i qMoveMask = _mm_set_epi8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 15, 13, 11, 9, 7, 5, 3, 1);
__m128i complexVal, iOutputVal, qOutputVal;
unsigned int eighthPoints = num_points / 8;
for(number = 0; number < eighthPoints; number++){
- complexVal = _mm_load_si128((__m128i*)complexVectorPtr); complexVectorPtr += 16;
+ complexVal = _mm_load_si128((__m128i*)complexVectorPtr); complexVectorPtr += 16; // aligned load
- iOutputVal = _mm_shuffle_epi8(complexVal, iMoveMask);
+ iOutputVal = _mm_shuffle_epi8(complexVal, iMoveMask); // shuffle 16 bytes of 128bit complexVal
qOutputVal = _mm_shuffle_epi8(complexVal, qMoveMask);
- iOutputVal = _mm_cvtepi8_epi16(iOutputVal);
- iOutputVal = _mm_slli_epi16(iOutputVal, 8);
+ iOutputVal = _mm_cvtepi8_epi16(iOutputVal); // fills 2-byte sign extended versions of lower 8 bytes of input to output
+ iOutputVal = _mm_slli_epi16(iOutputVal, 8); // shift in left by 8 bits, each of the 8 16-bit integers, shift in with zeros
qOutputVal = _mm_cvtepi8_epi16(qOutputVal);
qOutputVal = _mm_slli_epi16(qOutputVal, 8);
- _mm_store_si128((__m128i*)iBufferPtr, iOutputVal);
+ _mm_store_si128((__m128i*)iBufferPtr, iOutputVal); // aligned store
_mm_store_si128((__m128i*)qBufferPtr, qOutputVal);
iBufferPtr += 8;
@@ -45,12 +68,78 @@ static inline void volk_8ic_deinterleave_16i_x2_a_sse4_1(int16_t* iBuffer, int16
number = eighthPoints * 8;
for(; number < num_points; number++){
- *iBufferPtr++ = ((int16_t)*complexVectorPtr++) * 256;
+ *iBufferPtr++ = ((int16_t)*complexVectorPtr++) * 256; // load 8 bit Complexvector into 16 bit, shift left by 8 bits and store
*qBufferPtr++ = ((int16_t)*complexVectorPtr++) * 256;
}
}
#endif /* LV_HAVE_SSE4_1 */
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+/*!
+ \brief Deinterleaves the complex 8 bit vector into I & Q 16 bit vector data
+ \param complexVector The complex input vector
+ \param iBuffer The I buffer output data
+ \param qBuffer The Q buffer output data
+ \param num_points The number of complex data values to be deinterleaved
+*/
+static inline void volk_8ic_deinterleave_16i_x2_a_avx(int16_t* iBuffer, int16_t* qBuffer, const lv_8sc_t* complexVector, unsigned int num_points){
+ unsigned int number = 0;
+ const int8_t* complexVectorPtr = (int8_t*)complexVector;
+ int16_t* iBufferPtr = iBuffer;
+ int16_t* qBufferPtr = qBuffer;
+ __m128i iMoveMask = _mm_set_epi8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 14, 12, 10, 8, 6, 4, 2, 0); // set 16 byte values
+ __m128i qMoveMask = _mm_set_epi8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 15, 13, 11, 9, 7, 5, 3, 1);
+ __m256i complexVal, iOutputVal, qOutputVal;
+ __m128i complexVal1, complexVal0;
+ __m128i iOutputVal1, iOutputVal0, qOutputVal1, qOutputVal0;
+
+ unsigned int sixteenthPoints = num_points / 16;
+
+ for(number = 0; number < sixteenthPoints; number++){
+ complexVal = _mm256_load_si256((__m256i*)complexVectorPtr); complexVectorPtr += 32; // aligned load
+
+ // Extract from complexVal to iOutputVal and qOutputVal
+ complexVal1 = _mm256_extractf128_si256(complexVal, 1);
+ complexVal0 = _mm256_extractf128_si256(complexVal, 0);
+
+ iOutputVal1 = _mm_shuffle_epi8(complexVal1, iMoveMask); // shuffle 16 bytes of 128bit complexVal
+ iOutputVal0 = _mm_shuffle_epi8(complexVal0, iMoveMask);
+ qOutputVal1 = _mm_shuffle_epi8(complexVal1, qMoveMask);
+ qOutputVal0 = _mm_shuffle_epi8(complexVal0, qMoveMask);
+
+ iOutputVal1 = _mm_cvtepi8_epi16(iOutputVal1); // fills 2-byte sign extended versions of lower 8 bytes of input to output
+ iOutputVal1 = _mm_slli_epi16(iOutputVal1, 8); // shift in left by 8 bits, each of the 8 16-bit integers, shift in with zeros
+ iOutputVal0 = _mm_cvtepi8_epi16(iOutputVal0);
+ iOutputVal0 = _mm_slli_epi16(iOutputVal0, 8);
+
+ qOutputVal1 = _mm_cvtepi8_epi16(qOutputVal1);
+ qOutputVal1 = _mm_slli_epi16(qOutputVal1, 8);
+ qOutputVal0 = _mm_cvtepi8_epi16(qOutputVal0);
+ qOutputVal0 = _mm_slli_epi16(qOutputVal0, 8);
+
+ // Pack iOutputVal0,1 to iOutputVal
+ __m256i dummy = _mm256_setzero_si256();
+ iOutputVal = _mm256_insertf128_si256(dummy, iOutputVal0, 0);
+ iOutputVal = _mm256_insertf128_si256(iOutputVal, iOutputVal1, 1);
+ qOutputVal = _mm256_insertf128_si256(dummy, qOutputVal0, 0);
+ qOutputVal = _mm256_insertf128_si256(qOutputVal, qOutputVal1, 1);
+
+ _mm256_store_si256((__m256i*)iBufferPtr, iOutputVal); // aligned store
+ _mm256_store_si256((__m256i*)qBufferPtr, qOutputVal);
+
+ iBufferPtr += 16;
+ qBufferPtr += 16;
+ }
+
+ number = sixteenthPoints * 16;
+ for(; number < num_points; number++){
+ *iBufferPtr++ = ((int16_t)*complexVectorPtr++) * 256; // load 8 bit Complexvector into 16 bit, shift left by 8 bits and store
+ *qBufferPtr++ = ((int16_t)*complexVectorPtr++) * 256;
+ }
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_GENERIC
/*!
\brief Deinterleaves the complex 8 bit vector into I & Q 16 bit vector data
diff --git a/volk/kernels/volk/volk_8ic_deinterleave_real_16i.h b/volk/kernels/volk/volk_8ic_deinterleave_real_16i.h
index 82cedb2bb7..c22f828a88 100644
--- a/volk/kernels/volk/volk_8ic_deinterleave_real_16i.h
+++ b/volk/kernels/volk/volk_8ic_deinterleave_real_16i.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_8ic_deinterleave_real_16i_a_H
#define INCLUDED_volk_8ic_deinterleave_real_16i_a_H
@@ -41,6 +63,54 @@ static inline void volk_8ic_deinterleave_real_16i_a_sse4_1(int16_t* iBuffer, con
}
#endif /* LV_HAVE_SSE4_1 */
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+/*!
+ \brief Deinterleaves the complex 8 bit vector into I 16 bit vector data
+ \param complexVector The complex input vector
+ \param iBuffer The I buffer output data
+ \param num_points The number of complex data values to be deinterleaved
+*/
+static inline void volk_8ic_deinterleave_real_16i_a_avx(int16_t* iBuffer, const lv_8sc_t* complexVector, unsigned int num_points){
+ unsigned int number = 0;
+ const int8_t* complexVectorPtr = (int8_t*)complexVector;
+ int16_t* iBufferPtr = iBuffer;
+ __m128i moveMask = _mm_set_epi8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 14, 12, 10, 8, 6, 4, 2, 0);
+ __m256i complexVal, outputVal;
+ __m128i complexVal1, complexVal0, outputVal1, outputVal0;
+
+ unsigned int sixteenthPoints = num_points / 16;
+
+ for(number = 0; number < sixteenthPoints; number++){
+ complexVal = _mm256_load_si256((__m256i*)complexVectorPtr); complexVectorPtr += 32;
+
+ complexVal1 = _mm256_extractf128_si256(complexVal, 1);
+ complexVal0 = _mm256_extractf128_si256(complexVal, 0);
+
+ outputVal1 = _mm_shuffle_epi8(complexVal1, moveMask);
+ outputVal0 = _mm_shuffle_epi8(complexVal0, moveMask);
+
+ outputVal1 = _mm_cvtepi8_epi16(outputVal1);
+ outputVal1 = _mm_slli_epi16(outputVal1, 7);
+ outputVal0 = _mm_cvtepi8_epi16(outputVal0);
+ outputVal0 = _mm_slli_epi16(outputVal0, 7);
+
+ __m256i dummy = _mm256_setzero_si256();
+ outputVal = _mm256_insertf128_si256(dummy, outputVal0, 0);
+ outputVal = _mm256_insertf128_si256(outputVal, outputVal1, 1);
+ _mm256_store_si256((__m256i*)iBufferPtr, outputVal);
+
+ iBufferPtr += 16;
+ }
+
+ number = sixteenthPoints * 16;
+ for(; number < num_points; number++){
+ *iBufferPtr++ = ((int16_t)*complexVectorPtr++) * 128;
+ complexVectorPtr++;
+ }
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_GENERIC
/*!
diff --git a/volk/kernels/volk/volk_8ic_deinterleave_real_8i.h b/volk/kernels/volk/volk_8ic_deinterleave_real_8i.h
index 427c9abf55..e333306fac 100644
--- a/volk/kernels/volk/volk_8ic_deinterleave_real_8i.h
+++ b/volk/kernels/volk/volk_8ic_deinterleave_real_8i.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_VOLK_8sc_DEINTERLEAVE_REAL_8s_ALIGNED8_H
#define INCLUDED_VOLK_8sc_DEINTERLEAVE_REAL_8s_ALIGNED8_H
@@ -43,6 +65,64 @@ static inline void volk_8ic_deinterleave_real_8i_a_ssse3(int8_t* iBuffer, const
}
#endif /* LV_HAVE_SSSE3 */
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+/*!
+ \brief Deinterleaves the complex 8 bit vector into I vector data
+ \param complexVector The complex input vector
+ \param iBuffer The I buffer output data
+ \param num_points The number of complex data values to be deinterleaved
+*/
+
+static inline void volk_8ic_deinterleave_real_8i_a_avx(int8_t* iBuffer, const lv_8sc_t* complexVector, unsigned int num_points){
+ unsigned int number = 0;
+ const int8_t* complexVectorPtr = (int8_t*)complexVector;
+ int8_t* iBufferPtr = iBuffer;
+ __m128i moveMaskL = _mm_set_epi8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 14, 12, 10, 8, 6, 4, 2, 0);
+ __m128i moveMaskH = _mm_set_epi8(14, 12, 10, 8, 6, 4, 2, 0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80);
+ __m256i complexVal1, complexVal2, outputVal;
+ __m128i complexVal1H, complexVal1L, complexVal2H, complexVal2L, outputVal1, outputVal2;
+
+ unsigned int thirtysecondPoints = num_points / 32;
+
+ for(number = 0; number < thirtysecondPoints; number++){
+
+ complexVal1 = _mm256_load_si256((__m256i*)complexVectorPtr);
+ complexVectorPtr += 32;
+ complexVal2 = _mm256_load_si256((__m256i*)complexVectorPtr);
+ complexVectorPtr += 32;
+
+ complexVal1H = _mm256_extractf128_si256(complexVal1, 1);
+ complexVal1L = _mm256_extractf128_si256(complexVal1, 0);
+ complexVal2H = _mm256_extractf128_si256(complexVal2, 1);
+ complexVal2L = _mm256_extractf128_si256(complexVal2, 0);
+
+ complexVal1H = _mm_shuffle_epi8(complexVal1H, moveMaskH);
+ complexVal1L = _mm_shuffle_epi8(complexVal1L, moveMaskL);
+ outputVal1 = _mm_or_si128(complexVal1H, complexVal1L);
+
+
+ complexVal2H = _mm_shuffle_epi8(complexVal2H, moveMaskH);
+ complexVal2L = _mm_shuffle_epi8(complexVal2L, moveMaskL);
+ outputVal2 = _mm_or_si128(complexVal2H, complexVal2L);
+
+ __m256i dummy = _mm256_setzero_si256();
+ outputVal = _mm256_insertf128_si256(dummy, outputVal1, 0);
+ outputVal = _mm256_insertf128_si256(outputVal, outputVal2, 1);
+
+
+ _mm256_store_si256((__m256i*)iBufferPtr, outputVal);
+ iBufferPtr += 32;
+ }
+
+ number = thirtysecondPoints * 32;
+ for(; number < num_points; number++){
+ *iBufferPtr++ = *complexVectorPtr++;
+ complexVectorPtr++;
+ }
+}
+#endif /* LV_HAVE_AVX */
+
#ifdef LV_HAVE_GENERIC
/*!
\brief Deinterleaves the complex 8 bit vector into I vector data
diff --git a/volk/kernels/volk/volk_8ic_s32f_deinterleave_32f_x2.h b/volk/kernels/volk/volk_8ic_s32f_deinterleave_32f_x2.h
index 9e244c8fc2..a6115482ec 100644
--- a/volk/kernels/volk/volk_8ic_s32f_deinterleave_32f_x2.h
+++ b/volk/kernels/volk/volk_8ic_s32f_deinterleave_32f_x2.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_8ic_s32f_deinterleave_32f_x2_a_H
#define INCLUDED_volk_8ic_s32f_deinterleave_32f_x2_a_H
diff --git a/volk/kernels/volk/volk_8ic_s32f_deinterleave_real_32f.h b/volk/kernels/volk/volk_8ic_s32f_deinterleave_real_32f.h
index 56a1adcbb5..bbe2c26b70 100644
--- a/volk/kernels/volk/volk_8ic_s32f_deinterleave_real_32f.h
+++ b/volk/kernels/volk/volk_8ic_s32f_deinterleave_real_32f.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_8ic_s32f_deinterleave_real_32f_a_H
#define INCLUDED_volk_8ic_s32f_deinterleave_real_32f_a_H
diff --git a/volk/kernels/volk/volk_8ic_x2_multiply_conjugate_16ic.h b/volk/kernels/volk/volk_8ic_x2_multiply_conjugate_16ic.h
index 685a21ddcd..5b64c5218c 100644
--- a/volk/kernels/volk/volk_8ic_x2_multiply_conjugate_16ic.h
+++ b/volk/kernels/volk/volk_8ic_x2_multiply_conjugate_16ic.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_8ic_x2_multiply_conjugate_16ic_a_H
#define INCLUDED_volk_8ic_x2_multiply_conjugate_16ic_a_H
diff --git a/volk/kernels/volk/volk_8ic_x2_s32f_multiply_conjugate_32fc.h b/volk/kernels/volk/volk_8ic_x2_s32f_multiply_conjugate_32fc.h
index edb52ff509..d6cc1f09cd 100644
--- a/volk/kernels/volk/volk_8ic_x2_s32f_multiply_conjugate_32fc.h
+++ b/volk/kernels/volk/volk_8ic_x2_s32f_multiply_conjugate_32fc.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_8ic_x2_s32f_multiply_conjugate_32fc_a_H
#define INCLUDED_volk_8ic_x2_s32f_multiply_conjugate_32fc_a_H
diff --git a/volk/kernels/volk/volk_8u_conv_k7_r2puppet_8u.h b/volk/kernels/volk/volk_8u_conv_k7_r2puppet_8u.h
index 8d31e469f2..b398556ca8 100644
--- a/volk/kernels/volk/volk_8u_conv_k7_r2puppet_8u.h
+++ b/volk/kernels/volk/volk_8u_conv_k7_r2puppet_8u.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_8u_conv_k7_r2puppet_8u_H
#define INCLUDED_volk_8u_conv_k7_r2puppet_8u_H
diff --git a/volk/kernels/volk/volk_8u_x4_conv_k7_r2_8u.h b/volk/kernels/volk/volk_8u_x4_conv_k7_r2_8u.h
index ece8cf0f48..e21dfe1e01 100644
--- a/volk/kernels/volk/volk_8u_x4_conv_k7_r2_8u.h
+++ b/volk/kernels/volk/volk_8u_x4_conv_k7_r2_8u.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef INCLUDED_volk_8u_x4_conv_k7_r2_8u_H
#define INCLUDED_volk_8u_x4_conv_k7_r2_8u_H
diff --git a/volk/lib/CMakeLists.txt b/volk/lib/CMakeLists.txt
index 6cc4504cfa..37915e5552 100644
--- a/volk/lib/CMakeLists.txt
+++ b/volk/lib/CMakeLists.txt
@@ -406,10 +406,8 @@ if(${CMAKE_VERSION} VERSION_GREATER "2.8.9")
# if we find one that matches our current system architecture
# set up the assembler flags and include the source files
foreach(ARCH ${ASM_ARCHS_AVAILABLE})
- message(STATUS "--==>> -CFLAGS1: ${FULL_C_FLAGS}")
string(REGEX MATCH "${ARCH}" ASM_ARCH "${FULL_C_FLAGS}")
if( ASM_ARCH STREQUAL "armv7" )
- set(ASM-ATT $ENV{ASM})
message(STATUS "---- Adding ASM files") # we always use ATT syntax
message(STATUS "-- Detected armv7 architecture; enabling ASM")
# setup architecture specific assembler flags
@@ -422,13 +420,20 @@ if(${CMAKE_VERSION} VERSION_GREATER "2.8.9")
message(STATUS "Adding source file: ${asm_file}")
endforeach(asm_file)
endif()
- set(CMAKE_ASM-ATT_FLAGS_INIT ${ARCH_ASM_FLAGS})
- enable_language(ASM-ATT) # this must be after flags_init
- message(STATUS "asm flags: ${CMAKE_ASM-ATT_FLAGS}")
+ enable_language(ASM)
+ set(CMAKE_ASM_FLAGS ${ARCH_ASM_FLAGS})
+ message(STATUS "c flags: ${FULL_C_FLAGS}")
+ message(STATUS "asm flags: ${CMAKE_ASM_FLAGS}")
endforeach(ARCH)
else(${CMAKE_VERSION} VERSION_GREATER "2.8.9")
message(STATUS "Not enabling ASM support. CMake >= 2.8.10 required.")
+ foreach(machine_name ${available_machines})
+ string(REGEX MATCH "neon" NEON_MACHINE ${machine_name})
+ if( NEON_MACHINE STREQUAL "neon")
+ message(FATAL_ERROR "CMake >= 2.8.10 is required for ARM NEON support")
+ endif()
+ endforeach()
endif(${CMAKE_VERSION} VERSION_GREATER "2.8.9")
########################################################################
diff --git a/volk/lib/qa_utils.cc b/volk/lib/qa_utils.cc
index f30f0097ae..be20ed6585 100644
--- a/volk/lib/qa_utils.cc
+++ b/volk/lib/qa_utils.cc
@@ -5,7 +5,9 @@
#include <boost/tokenizer.hpp>
#include <boost/xpressive/xpressive.hpp>
#include <iostream>
+#include <fstream>
#include <vector>
+#include <map>
#include <list>
#include <ctime>
#include <cmath>
@@ -245,7 +247,7 @@ bool fcompare(t *in1, t *in2, unsigned int vlen, float tol) {
}
}
// the primary test is the percent different greater than given tol
- else if(fabs(((t *)(in1))[i] - ((t *)(in2))[i])/(((t *)in1)[i]) > tol) {
+ else if(fabs(((t *)(in1))[i] - ((t *)(in2))[i])/fabs(((t *)in1)[i]) > tol) {
fail=true;
if(print_max_errs-- > 0) {
std::cout << "offset " << i << " in1: " << t(((t *)(in1))[i]) << " in2: " << t(((t *)(in2))[i]) << std::endl;
@@ -328,9 +330,9 @@ bool run_volk_tests(volk_func_desc_t desc,
lv_32fc_t scalar,
int vlen,
int iter,
- std::vector<std::string> *best_arch_vector = 0,
- std::string puppet_master_name = "NULL",
- bool benchmark_mode,
+ std::vector<volk_test_results_t> *results,
+ std::string puppet_master_name,
+ bool benchmark_mode,
std::string kernel_regex
) {
boost::xpressive::sregex kernel_expression = boost::xpressive::sregex::compile(kernel_regex);
@@ -338,6 +340,12 @@ bool run_volk_tests(volk_func_desc_t desc,
// in this case we have a regex and are only looking to test one kernel
return false;
}
+ if(results) {
+ results->push_back(volk_test_results_t());
+ results->back().name = name;
+ results->back().vlen = vlen;
+ results->back().iter = iter;
+ }
std::cout << "RUN_VOLK_TESTS: " << name << "(" << vlen << "," << iter << ")" << std::endl;
// The multiply and lv_force_cast_hf are work arounds for GNU Radio bugs 582 and 583
@@ -453,6 +461,13 @@ bool run_volk_tests(volk_func_desc_t desc,
end = clock();
double arch_time = 1000.0 * (double)(end-start)/(double)CLOCKS_PER_SEC;
std::cout << arch_list[i] << " completed in " << arch_time << "ms" << std::endl;
+ if(results) {
+ volk_test_time_t result;
+ result.name = arch_list[i];
+ result.time = arch_time;
+ result.units = "ms";
+ results->back().results[result.name] = result;
+ }
profile_times.push_back(arch_time);
}
@@ -553,13 +568,14 @@ bool run_volk_tests(volk_func_desc_t desc,
std::cout << "Best aligned arch: " << best_arch_a << std::endl;
std::cout << "Best unaligned arch: " << best_arch_u << std::endl;
- if(best_arch_vector) {
+ if(results) {
if(puppet_master_name == "NULL") {
- best_arch_vector->push_back(name + " " + best_arch_a + " " + best_arch_u);
- }
- else {
- best_arch_vector->push_back(puppet_master_name + " " + best_arch_a + " " + best_arch_u);
+ results->back().config_name = name;
+ } else {
+ results->back().config_name = puppet_master_name;
}
+ results->back().best_arch_a = best_arch_a;
+ results->back().best_arch_u = best_arch_u;
}
return fail_global;
diff --git a/volk/lib/qa_utils.h b/volk/lib/qa_utils.h
index fc1a0239eb..7ca8b8d1e8 100644
--- a/volk/lib/qa_utils.h
+++ b/volk/lib/qa_utils.h
@@ -3,7 +3,10 @@
#include <cstdlib>
#include <string>
+#include <iostream>
+#include <fstream>
#include <vector>
+#include <map>
#include <volk/volk.h>
#include <volk/volk_common.h>
@@ -21,10 +24,46 @@ volk_type_t volk_type_from_string(std::string);
float uniform(void);
void random_floats(float *buf, unsigned n);
-bool run_volk_tests(volk_func_desc_t, void(*)(), std::string, float, lv_32fc_t, int, int, std::vector<std::string> *, std::string, bool benchmark_mode=false, std::string kernel_regex="");
+class volk_test_time_t {
+ public:
+ std::string name;
+ double time;
+ std::string units;
+};
+
+class volk_test_results_t {
+ public:
+ std::string name;
+ std::string config_name;
+ int vlen;
+ int iter;
+ std::map<std::string, volk_test_time_t> results;
+ std::string best_arch_a;
+ std::string best_arch_u;
+};
+
+bool run_volk_tests(
+ volk_func_desc_t,
+ void(*)(),
+ std::string,
+ float,
+ lv_32fc_t,
+ int,
+ int,
+ std::vector<volk_test_results_t> *results = NULL,
+ std::string puppet_master_name = "NULL",
+ bool benchmark_mode=false,
+ std::string kernel_regex=""
+ );
-#define VOLK_RUN_TESTS(func, tol, scalar, len, iter) BOOST_AUTO_TEST_CASE(func##_test) { BOOST_CHECK_EQUAL(run_volk_tests(func##_get_func_desc(), (void (*)())func##_manual, std::string(#func), tol, scalar, len, iter, 0, "NULL"), 0); }
+#define VOLK_RUN_TESTS(func, tol, scalar, len, iter) \
+ BOOST_AUTO_TEST_CASE(func##_test) { \
+ BOOST_CHECK_EQUAL(run_volk_tests( \
+ func##_get_func_desc(), (void (*)())func##_manual, \
+ std::string(#func), tol, scalar, len, iter, 0, "NULL"), \
+ 0); \
+ }
#define VOLK_PROFILE(func, tol, scalar, len, iter, results, bnmode, kernel_regex) run_volk_tests(func##_get_func_desc(), (void (*)())func##_manual, std::string(#func), tol, scalar, len, iter, results, "NULL", bnmode, kernel_regex)
#define VOLK_PUPPET_PROFILE(func, puppet_master_func, tol, scalar, len, iter, results, bnmode, kernel_regex) run_volk_tests(func##_get_func_desc(), (void (*)())func##_manual, std::string(#func), tol, scalar, len, iter, results, std::string(#puppet_master_func), bnmode, kernel_regex)
typedef void (*volk_fn_1arg)(void *, unsigned int, const char*); //one input, operate in place
diff --git a/volk/lib/testqa.cc b/volk/lib/testqa.cc
index bc97ad16e5..7807ce40a6 100644
--- a/volk/lib/testqa.cc
+++ b/volk/lib/testqa.cc
@@ -44,6 +44,15 @@ VOLK_RUN_TESTS(volk_16u_byteswap, 0, 0, 20462, 1);
VOLK_RUN_TESTS(volk_32f_accumulator_s32f, 1e-4, 0, 20462, 1);
VOLK_RUN_TESTS(volk_32f_x2_add_32f, 1e-4, 0, 20462, 1);
VOLK_RUN_TESTS(volk_32fc_32f_multiply_32fc, 1e-4, 0, 20462, 1);
+VOLK_RUN_TESTS(volk_32f_log2_32f, 1.5e-1, 0, 20462, 1);
+VOLK_RUN_TESTS(volk_32f_expfast_32f, 1e-1, 0, 20462, 1);
+VOLK_RUN_TESTS(volk_32f_x2_pow_32f, 1e-2, 0, 20462, 1);
+VOLK_RUN_TESTS(volk_32f_sin_32f, 1e-6, 0, 20462, 1);
+VOLK_RUN_TESTS(volk_32f_cos_32f, 1e-6, 0, 20462, 1);
+VOLK_RUN_TESTS(volk_32f_tan_32f, 1e-6, 0, 20462, 1);
+VOLK_RUN_TESTS(volk_32f_atan_32f, 1e-3, 0, 20462, 1);
+VOLK_RUN_TESTS(volk_32f_asin_32f, 1e-3, 0, 20462, 1);
+VOLK_RUN_TESTS(volk_32f_acos_32f, 1e-3, 0, 20462, 1);
VOLK_RUN_TESTS(volk_32fc_s32f_power_32fc, 1e-4, 0, 20462, 1);
VOLK_RUN_TESTS(volk_32f_s32f_calc_spectral_noise_floor_32f, 1e-4, 20.0, 20462, 1);
VOLK_RUN_TESTS(volk_32fc_s32f_atan2_32f, 1e-4, 10.0, 20462, 1);
@@ -88,12 +97,12 @@ VOLK_RUN_TESTS(volk_32i_x2_and_32i, 0, 0, 20462, 1);
VOLK_RUN_TESTS(volk_32i_s32f_convert_32f, 1e-4, 100, 20462, 1);
VOLK_RUN_TESTS(volk_32i_x2_or_32i, 0, 0, 20462, 1);
VOLK_RUN_TESTS(volk_32u_byteswap, 0, 0, 20462, 1);
-//VOLK_RUN_TESTS(volk_32u_popcnt, 0, 0, 2046, 10000);
+VOLK_RUN_TESTS(volk_32u_popcntpuppet_32u, 0, 0, 2046, 10000);
VOLK_RUN_TESTS(volk_64f_convert_32f, 1e-4, 0, 20462, 1);
VOLK_RUN_TESTS(volk_64f_x2_max_64f, 1e-4, 0, 20462, 1);
VOLK_RUN_TESTS(volk_64f_x2_min_64f, 1e-4, 0, 20462, 1);
VOLK_RUN_TESTS(volk_64u_byteswap, 0, 0, 20462, 1);
-//VOLK_RUN_TESTS(volk_64u_popcnt, 0, 0, 2046, 10000);
+VOLK_RUN_TESTS(volk_64u_popcntpuppet_64u, 0, 0, 2046, 10000);
VOLK_RUN_TESTS(volk_8ic_deinterleave_16i_x2, 0, 0, 20462, 1);
VOLK_RUN_TESTS(volk_8ic_s32f_deinterleave_32f_x2, 1e-4, 100, 20462, 1);
VOLK_RUN_TESTS(volk_8ic_deinterleave_real_16i, 0, 256, 20462, 1);
@@ -114,3 +123,4 @@ VOLK_RUN_TESTS(volk_8u_conv_k7_r2puppet_8u, 0, 0, 2060, 1);
VOLK_RUN_TESTS(volk_32f_invsqrt_32f, 1e-2, 0, 20462, 1);
VOLK_RUN_TESTS(volk_32f_binary_slicer_32i, 0, 0, 20462, 1);
VOLK_RUN_TESTS(volk_32f_binary_slicer_8i, 0, 0, 20462, 1);
+VOLK_RUN_TESTS(volk_32f_tanh_32f, 1e-6, 0, 20462, 1);