diff options
author | Tom Rondeau <trondeau@vt.edu> | 2013-03-17 11:43:10 -0400 |
---|---|---|
committer | Tom Rondeau <trondeau@vt.edu> | 2013-03-17 11:43:10 -0400 |
commit | ee2b700f72503d6e7f62adbfb7dff9997b9cb003 (patch) | |
tree | 2c7e91d03fb5c605c6deebac9077c1bc41bce13d | |
parent | f15400470ce5cb68f5339ead7af726b8bbafd364 (diff) | |
parent | 65d88f0b28e233c82bc4f0c07072085a3d18c163 (diff) |
Merge branch 'master' into next
Conflicts:
gr-blocks/swig/blocks_swig.i
70 files changed, 4900 insertions, 1 deletions
diff --git a/gr-blocks/grc/blocks_block_tree.xml b/gr-blocks/grc/blocks_block_tree.xml index 90d94bdb29..face908df0 100644 --- a/gr-blocks/grc/blocks_block_tree.xml +++ b/gr-blocks/grc/blocks_block_tree.xml @@ -39,6 +39,8 @@ <block>blocks_message_burst_source</block> <block>blocks_udp_source</block> <block>blocks_wavfile_source</block> + <block>blocks_vector_source_x</block> + <block>blocks_null_source</block> </cat> <cat> <name>Sinks (New)</name> @@ -51,6 +53,8 @@ <block>blocks_tagged_file_sink</block> <block>blocks_udp_sink</block> <block>blocks_wavfile_sink</block> + <block>blocks_vector_sink_x</block> + <block>blocks_null_sink</block> </cat> <cat> <name>Math Operations (New) </name> @@ -123,6 +127,8 @@ <block>blocks_stretch_ff</block> <block>blocks_threshold_ff</block> <block>blocks_burst_tagger</block> + <block>blocks_endian_swap</block> + <block>blocks_vector_insert_x</block> </cat> <cat> <name>Misc Conversions (New) </name> @@ -135,6 +141,10 @@ <name>Misc (New) </name> <block>blocks_throttle</block> <block>blocks_probe_rate</block> + <block>blocks_head</block> + <block>blocks_skiphead</block> + <block>blocks_copy</block> + <block>blocks_nop</block> </cat> <cat> <name>Networking</name> diff --git a/gr-blocks/grc/blocks_copy.xml b/gr-blocks/grc/blocks_copy.xml new file mode 100644 index 0000000000..55c4b343d3 --- /dev/null +++ b/gr-blocks/grc/blocks_copy.xml @@ -0,0 +1,75 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Copy +################################################### + --> +<block> + <name>Copy</name> + <key>blocks_copy</key> + <import>from gnuradio import blocks</import> + <make>blocks.copy($type.size*$vlen) +self.$(id).set_enabled($enabled)</make> + <callback>set_enabled($enabled)</callback> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Enabled</name> + <key>enabled</key> + <value>True</value> + <type>bool</type> + <option> + <name>Enabled</name> + <key>True</key> + </option> + <option> + <name>Disabled</name> + <key>False</key> + </option> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_endian_swap.xml b/gr-blocks/grc/blocks_endian_swap.xml new file mode 100644 index 0000000000..5fea420664 --- /dev/null +++ b/gr-blocks/grc/blocks_endian_swap.xml @@ -0,0 +1,41 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Add Block: +## all types, 1 output, 2 to inf inputs +################################################### + --> +<block> + <name>Endian Swap</name> + <key>blocks_endian_swap</key> + <import>from gnuradio import blocks</import> + <make>blocks.endian_swap($type.size)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:8</opt> + </option> + <option> + <name>Int</name> + <key>s32</key> + <opt>size:4</opt> + </option> + <option> + <name>Short</name> + <key>s16</key> + <opt>size:2</opt> + </option> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/gr-blocks/grc/blocks_head.xml b/gr-blocks/grc/blocks_head.xml new file mode 100644 index 0000000000..8b6e67820c --- /dev/null +++ b/gr-blocks/grc/blocks_head.xml @@ -0,0 +1,65 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Head +################################################### + --> +<block> + <name>Head</name> + <key>blocks_head</key> + <import>from gnuradio import blocks</import> + <make>blocks.head($type.size*$vlen, $num_items)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Num Items</name> + <key>num_items</key> + <value>1024</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_nop.xml b/gr-blocks/grc/blocks_nop.xml new file mode 100644 index 0000000000..d38c23839d --- /dev/null +++ b/gr-blocks/grc/blocks_nop.xml @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Nop +################################################### + --> +<block> + <name>Nop</name> + <key>blocks_nop</key> + <import>from gnuradio import blocks</import> + <make>blocks.nop($type.size*$vlen)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Num Ports</name> + <key>num_ports</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_ports > 0</check> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_ports</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_ports</nports> + </source> +</block> diff --git a/gr-blocks/grc/blocks_null_sink.xml b/gr-blocks/grc/blocks_null_sink.xml new file mode 100644 index 0000000000..2ae20e619a --- /dev/null +++ b/gr-blocks/grc/blocks_null_sink.xml @@ -0,0 +1,54 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Null Sink +################################################### + --> +<block> + <name>Null Sink</name> + <key>blocks_null_sink</key> + <import>from gnuradio import blocks</import> + <make>blocks.null_sink($type.size*$vlen)</make> + <param> + <name>Input Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> +</block> diff --git a/gr-blocks/grc/blocks_null_source.xml b/gr-blocks/grc/blocks_null_source.xml new file mode 100644 index 0000000000..01d3905cab --- /dev/null +++ b/gr-blocks/grc/blocks_null_source.xml @@ -0,0 +1,54 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Null Source +################################################### + --> +<block> + <name>Null Source</name> + <key>blocks_null_source</key> + <import>from gnuradio import blocks</import> + <make>blocks.null_source($type.size*$vlen)</make> + <param> + <name>Output Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_skiphead.xml b/gr-blocks/grc/blocks_skiphead.xml new file mode 100644 index 0000000000..7d90862830 --- /dev/null +++ b/gr-blocks/grc/blocks_skiphead.xml @@ -0,0 +1,65 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Skip Head +################################################### + --> +<block> + <name>Skip Head</name> + <key>blocks_skiphead</key> + <import>from gnuradio import blocks</import> + <make>blocks.skiphead($type.size*$vlen, $num_items)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Num Items</name> + <key>num_items</key> + <value>1024</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_vector_insert_x.xml b/gr-blocks/grc/blocks_vector_insert_x.xml new file mode 100644 index 0000000000..2bc7ada2e6 --- /dev/null +++ b/gr-blocks/grc/blocks_vector_insert_x.xml @@ -0,0 +1,80 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Vector Source +################################################### + --> +<block> + <name>Vector Insert</name> + <key>blocks_vector_insert_x</key> + <import>from gnuradio import blocks</import> + <make>blocks.vector_insert_$(type.fcn)($vector, $period, $offset)</make> + <param> + <name>Output Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Byte</name> + <key>byte</key> + <opt>fcn:b</opt> + <opt>vec_type:int_vector</opt> + </option> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:c</opt> + <opt>vec_type:complex_vector</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:f</opt> + <opt>vec_type:real_vector</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:i</opt> + <opt>vec_type:int_vector</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:s</opt> + <opt>vec_type:int_vector</opt> + </option> + </param> + <param> + <name>Vector</name> + <key>vector</key> + <value>0, 0, 0</value> + <type>$type.vec_type</type> + </param> + <param> + <name>Periodicity</name> + <key>period</key> + <value>100</value> + <type>int</type> + </param> + <param> + <name>Offset</name> + <key>offset</key> + <value>0</value> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> + + <doc> + Periodicity, the length of the periodicity at which the vector should be inserted at the output. + (i.e. one vector for every N output items) + + Offset sepcifies where in the cycle period we should begin at. + </doc> +</block> diff --git a/gr-blocks/grc/blocks_vector_sink_x.xml b/gr-blocks/grc/blocks_vector_sink_x.xml new file mode 100644 index 0000000000..7f51731975 --- /dev/null +++ b/gr-blocks/grc/blocks_vector_sink_x.xml @@ -0,0 +1,54 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Vector sink +################################################### + --> +<block> + <name>Vector Sink</name> + <key>blocks_vector_sink_x</key> + <import>from gnuradio import blocks</import> + <make>blocks.vector_sink_$(type.fcn)($vlen)</make> + <param> + <name>Input Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:c</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:f</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:i</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:s</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>fcn:b</opt> + </option> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> +</block> diff --git a/gr-blocks/grc/blocks_vector_source_x.xml b/gr-blocks/grc/blocks_vector_source_x.xml new file mode 100644 index 0000000000..5221c4f3eb --- /dev/null +++ b/gr-blocks/grc/blocks_vector_source_x.xml @@ -0,0 +1,85 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Vector Source +################################################### + --> +<block> + <name>Vector Source</name> + <key>blocks_vector_source_x</key> + <import>from gnuradio import blocks</import> + <make>blocks.vector_source_$(type.fcn)($vector, $repeat, $vlen, $tags)</make> + <param> + <name>Output Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:c</opt> + <opt>vec_type:complex_vector</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:f</opt> + <opt>vec_type:real_vector</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:i</opt> + <opt>vec_type:int_vector</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:s</opt> + <opt>vec_type:int_vector</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>fcn:b</opt> + <opt>vec_type:int_vector</opt> + </option> + </param> + <param> + <name>Vector</name> + <key>vector</key> + <value>[0, 0, 0]</value> + <type>raw</type> + </param> + <param> + <name>Tags</name> + <key>tags</key> + <value>[]</value> + <type>raw</type> + </param> + <param> + <name>Repeat</name> + <key>repeat</key> + <value>True</value> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/include/blocks/CMakeLists.txt b/gr-blocks/include/blocks/CMakeLists.txt index 0f158ff473..a922af6426 100644 --- a/gr-blocks/include/blocks/CMakeLists.txt +++ b/gr-blocks/include/blocks/CMakeLists.txt @@ -88,6 +88,9 @@ expand_h(sub_XX ss ii ff cc) expand_h(xor_XX bb ss ii) expand_h(packed_to_unpacked_XX bb ss ii) expand_h(unpacked_to_packed_XX bb ss ii) +expand_h(vector_insert_X b s i f c) +expand_h(vector_sink_X b s i f c) +expand_h(vector_source_X b s i f c) add_custom_target(blocks_generated_includes DEPENDS ${generated_includes} @@ -106,10 +109,14 @@ install(FILES fxpt_nco.h fxpt_vco.h log2_const.h + rotator.h nco.h vco.h wavfile.h add_ff.h + annotator_1to1.h + annotator_alltoall.h + annotator_raw.h bin_statistics_f.h burst_tagger.h char_to_float.h @@ -122,8 +129,10 @@ install(FILES complex_to_mag_squared.h complex_to_arg.h conjugate_cc.h + copy.h deinterleave.h delay.h + endian_swap.h file_source.h file_meta_sink.h file_meta_source.h @@ -132,6 +141,7 @@ install(FILES float_to_int.h float_to_short.h float_to_uchar.h + head.h int_to_float.h interleave.h interleaved_short_to_complex.h @@ -148,6 +158,9 @@ install(FILES multiply_const_cc.h multiply_const_ff.h nlog10_ff.h + nop.h + null_sink.h + null_source.h pack_k_bits_bb.h patterned_interleaver.h pdu.h @@ -162,6 +175,7 @@ install(FILES rms_ff.h short_to_char.h short_to_float.h + skiphead.h socket_pdu.h stream_mux.h stream_to_streams.h @@ -182,6 +196,7 @@ install(FILES udp_source.h unpack_k_bits_bb.h vco_f.h + vector_map.h vector_to_stream.h vector_to_streams.h wavfile_sink.h diff --git a/gr-blocks/include/blocks/annotator_1to1.h b/gr-blocks/include/blocks/annotator_1to1.h new file mode 100644 index 0000000000..6cc8db6eef --- /dev/null +++ b/gr-blocks/include/blocks/annotator_1to1.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_ANNOTATOR_1TO1_H +#define INCLUDED_GR_ANNOTATOR_1TO1_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief 1-to-1 stream annotator testing block. FOR TESTING PURPOSES ONLY. + * + * This block creates tags to be sent downstream every 10,000 + * items it sees. The tags contain the name and ID of the + * instantiated block, use "seq" as a key, and have a counter that + * increments by 1 for every tag produced that is used as the + * tag's value. The tags are propagated using the 1-to-1 policy. + * + * It also stores a copy of all tags it sees flow past it. These + * tags can be recalled externally with the data() member. + * + * This block is only meant for testing and showing how to use the tags. + */ + class BLOCKS_API annotator_1to1 : virtual public gr_sync_block + { + public: + // gr::blocks::annotator_1to1::sptr + typedef boost::shared_ptr<annotator_1to1> sptr; + + static sptr make(int when, size_t sizeof_stream_item); + + virtual std::vector<gr_tag_t> data() const = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_ANNOTATOR_1TO1_H */ diff --git a/gr-blocks/include/blocks/annotator_alltoall.h b/gr-blocks/include/blocks/annotator_alltoall.h new file mode 100644 index 0000000000..558aea69ca --- /dev/null +++ b/gr-blocks/include/blocks/annotator_alltoall.h @@ -0,0 +1,61 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_ANNOTATOR_ALLTOALL_H +#define INCLUDED_GR_ANNOTATOR_ALLTOALL_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief All-to-all stream annotator testing block. FOR TESTING PURPOSES ONLY. + * + * This block creates tags to be sent downstream every 10,000 + * items it sees. The tags contain the name and ID of the + * instantiated block, use "seq" as a key, and have a counter that + * increments by 1 for every tag produced that is used as the + * tag's value. The tags are propagated using the all-to-all + * policy. + * + * It also stores a copy of all tags it sees flow past it. These + * tags can be recalled externally with the data() member. + * + * This block is only meant for testing and showing how to use the tags. + */ + class BLOCKS_API annotator_alltoall : virtual public gr_sync_block + { + public: + // gr::blocks::annotator_alltoall::sptr + typedef boost::shared_ptr<annotator_alltoall> sptr; + + static sptr make(int when, size_t sizeof_stream_item); + + virtual std::vector<gr_tag_t> data() const = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_ANNOTATOR_ALLTOALL_H */ diff --git a/gr-blocks/include/blocks/annotator_raw.h b/gr-blocks/include/blocks/annotator_raw.h new file mode 100644 index 0000000000..e835f0bd8d --- /dev/null +++ b/gr-blocks/include/blocks/annotator_raw.h @@ -0,0 +1,57 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_ANNOTATOR_RAW_H +#define INCLUDED_GR_ANNOTATOR_RAW_H + +#include <blocks/api.h> +#include <gr_sync_block.h> +#include <gr_tags.h> + +namespace gr { + namespace blocks { + + /*! + * \brief raw stream annotator testing block. + * + * This block creates arbitrary tags to be sent downstream blocks + * to be sent are set manually via accessor methods and are sent + * only once. + * + * This block is intended for testing of tag related blocks + */ + class BLOCKS_API annotator_raw : virtual public gr_sync_block + { + public: + // gr::blocks::annotator_raw::sptr + typedef boost::shared_ptr<annotator_raw> sptr; + + static sptr make(size_t sizeof_stream_item); + + // insert a tag to be added + void add_tag(uint64_t offset, pmt::pmt_t key, pmt::pmt_t val); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_ANNOTATOR_RAW_H */ diff --git a/gr-blocks/include/blocks/copy.h b/gr-blocks/include/blocks/copy.h new file mode 100644 index 0000000000..5ed0ea0e92 --- /dev/null +++ b/gr-blocks/include/blocks/copy.h @@ -0,0 +1,54 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2009,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_COPY_H +#define INCLUDED_GR_COPY_H + +#include <blocks/api.h> +#include <gr_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief output[i] = input[i] + * \ingroup misc_blk + * + * When enabled (default), this block copies its input to its + * output. When disabled, this block drops its input on the floor. + */ + class BLOCKS_API copy : virtual public gr_block + { + public: + // gr::blocks::copy::sptr + typedef boost::shared_ptr<copy> sptr; + + static sptr make(size_t itemsize); + + virtual void set_enabled(bool enable) = 0; + virtual bool enabled() const = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_COPY_H */ diff --git a/gr-blocks/include/blocks/endian_swap.h b/gr-blocks/include/blocks/endian_swap.h new file mode 100644 index 0000000000..4b5a76218e --- /dev/null +++ b/gr-blocks/include/blocks/endian_swap.h @@ -0,0 +1,50 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_ENDIAN_SWAP_H +#define INCLUDED_GR_ENDIAN_SWAP_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief Convert stream of items into thier byte swapped version + * + * \param item_size_bytes number of bytes per item, 1=no-op, + * 2=uint16_t, 4=uint32_t, 8=uint64_t + */ + class BLOCKS_API endian_swap : virtual public gr_sync_block + { + public: + // gr::blocks::endian_swap::sptr + typedef boost::shared_ptr<endian_swap> sptr; + + static sptr make(size_t item_size_bytes=1); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_ENDIAN_SWAP_H */ diff --git a/gr-blocks/include/blocks/head.h b/gr-blocks/include/blocks/head.h new file mode 100644 index 0000000000..cc7d3808e5 --- /dev/null +++ b/gr-blocks/include/blocks/head.h @@ -0,0 +1,55 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2012,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_HEAD_H +#define INCLUDED_GR_HEAD_H + +#include <blocks/api.h> +#include <gr_sync_block.h> +#include <stddef.h> // size_t + +namespace gr { + namespace blocks { + + /*! + * \brief copies the first N items to the output then signals done + * \ingroup slicedice_blk + * + * Useful for building test cases + */ + class BLOCKS_API head : virtual public gr_sync_block + { + public: + // gr::blocks::head::sptr + typedef boost::shared_ptr<head> sptr; + + static sptr make(size_t sizeof_stream_item, + uint64_t nitems); + + virtual void reset() = 0; + virtual void set_length(int nitems) = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_HEAD_H */ diff --git a/gr-blocks/include/blocks/nop.h b/gr-blocks/include/blocks/nop.h new file mode 100644 index 0000000000..b3135e1cc8 --- /dev/null +++ b/gr-blocks/include/blocks/nop.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_NOP_H +#define INCLUDED_GR_NOP_H + +#include <blocks/api.h> +#include <gr_block.h> +#include <stddef.h> // size_t + +namespace gr { + namespace blocks { + + /*! + * \brief Does nothing. Used for testing only. + * \ingroup misc_blk + */ + class BLOCKS_API nop : virtual public gr_block + { + public: + // gr::blocks::nop::sptr + typedef boost::shared_ptr<nop> sptr; + + /*! + * Build a nop block. + * + * \param sizeof_stream_item size of the stream items in bytes. + */ + static sptr make(size_t sizeof_stream_item); + + virtual int nmsgs_received() const = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_NOP_H */ diff --git a/gr-blocks/include/blocks/null_sink.h b/gr-blocks/include/blocks/null_sink.h new file mode 100644 index 0000000000..c13a7552c6 --- /dev/null +++ b/gr-blocks/include/blocks/null_sink.h @@ -0,0 +1,55 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_NULL_SINK_H +#define INCLUDED_GR_NULL_SINK_H + +#include <blocks/api.h> +#include <gr_sync_block.h> +#include <stddef.h> // size_t + +namespace gr { + namespace blocks { + + /*! + * \brief Bit bucket. Use as a termination point when a sink is + * required and we don't want to do anything real. + * \ingroup sink_blk + */ + class BLOCKS_API null_sink : virtual public gr_sync_block + { + public: + // gr::blocks::null_sink::sptr + typedef boost::shared_ptr<null_sink> sptr; + + /*! + * Build a null sink block. + * + * \param sizeof_stream_item size of the stream items in bytes. + */ + static sptr make(size_t sizeof_stream_item); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_NULL_SINK_H */ diff --git a/gr-blocks/include/blocks/null_source.h b/gr-blocks/include/blocks/null_source.h new file mode 100644 index 0000000000..904a0c1ba3 --- /dev/null +++ b/gr-blocks/include/blocks/null_source.h @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_NULL_SOURCE_H +#define INCLUDED_GR_NULL_SOURCE_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief A source of zeros used mainly for testing. + * \ingroup source_blk + */ + class BLOCKS_API null_source : virtual public gr_sync_block + { + public: + // gr::blocks::null_source::sptr + typedef boost::shared_ptr<null_source> sptr; + + /*! + * Build a null source block. + * + * \param sizeof_stream_item size of the stream items in bytes. + */ + static sptr make(size_t sizeof_stream_item); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_NULL_SOURCE_H */ diff --git a/gr-blocks/include/blocks/rotator.h b/gr-blocks/include/blocks/rotator.h new file mode 100644 index 0000000000..96ece63574 --- /dev/null +++ b/gr-blocks/include/blocks/rotator.h @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 2003,2008,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _GR_ROTATOR_H_ +#define _GR_ROTATOR_H_ + +#include <blocks/api.h> +#include <gr_complex.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API rotator + { + private: + gr_complex d_phase; + gr_complex d_phase_incr; + unsigned int d_counter; + + public: + rotator() : d_phase(1), d_phase_incr(1), d_counter(0) + { } + + void set_phase(gr_complex phase) { d_phase = phase / abs(phase); } + void set_phase_incr(gr_complex incr) { d_phase_incr = incr / abs(incr); } + + gr_complex rotate(gr_complex in) + { + d_counter++; + + gr_complex z = in * d_phase; // rotate in by phase + d_phase *= d_phase_incr; // incr our phase (complex mult == add phases) + + if((d_counter % 512) == 0) + d_phase /= abs(d_phase); // Normalize to ensure multiplication is rotation + + return z; + } + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* _GR_ROTATOR_H_ */ diff --git a/gr-blocks/include/blocks/skiphead.h b/gr-blocks/include/blocks/skiphead.h new file mode 100644 index 0000000000..e6745af8ea --- /dev/null +++ b/gr-blocks/include/blocks/skiphead.h @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_SKIPHEAD_H +#define INCLUDED_GR_SKIPHEAD_H + +#include <blocks/api.h> +#include <gr_sync_block.h> +#include <stddef.h> // size_t + +namespace gr { + namespace blocks { + + /*! + * \brief skips the first N items, from then on copies items to the output + * \ingroup slicedice_blk + * + * Useful for building test cases and sources which have metadata + * or junk at the start + */ + class BLOCKS_API skiphead : virtual public gr_block + { + public: + // gr::blocks::skiphead::sptr + typedef boost::shared_ptr<skiphead> sptr; + + static sptr make(size_t itemsize, + uint64_t nitems_to_skip); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_SKIPHEAD_H */ diff --git a/gr-blocks/include/blocks/vector_insert_X.h.t b/gr-blocks/include/blocks/vector_insert_X.h.t new file mode 100644 index 0000000000..aeb4a5248a --- /dev/null +++ b/gr-blocks/include/blocks/vector_insert_X.h.t @@ -0,0 +1,54 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012-2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <blocks/api.h> +#include <gr_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief source of @TYPE@'s that gets its data from a vector + * \ingroup source_blk + */ + class BLOCKS_API @NAME@ : virtual public gr_block + { + public: + // gr::blocks::@NAME@::sptr + typedef boost::shared_ptr<@NAME@> sptr; + + static sptr make(const std::vector<@TYPE@> &data, + int periodicity, int offset=0); + + virtual void rewind() = 0; + virtual void set_data(const std::vector<@TYPE@> &data) = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-blocks/include/blocks/vector_map.h b/gr-blocks/include/blocks/vector_map.h new file mode 100644 index 0000000000..64c8744975 --- /dev/null +++ b/gr-blocks/include/blocks/vector_map.h @@ -0,0 +1,71 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_VECTOR_MAP_H +#define INCLUDED_GR_VECTOR_MAP_H + +#include <blocks/api.h> +#include <vector> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief Maps elements from a set of input vectors to a set of output vectors. + * \ingroup slicedice_blk + * + * If in[i] is the input vector in the i'th stream then the output + * vector in the j'th stream is: + * + * out[j][k] = in[mapping[j][k][0]][mapping[j][k][1]] + * + * That is mapping is of the form (out_stream1_mapping, + * out_stream2_mapping, ...) and out_stream1_mapping is of the + * form (element1_mapping, element2_mapping, ...) and + * element1_mapping is of the form (in_stream, in_element). + */ + class BLOCKS_API vector_map : virtual public gr_sync_block + { + public: + // gr::blocks::vector_map::sptr + typedef boost::shared_ptr<vector_map> sptr; + + /*! + * Build a vector map block. + * + * \param item_size (integer) size of vector elements + * \param in_vlens (vector of integers) number of elements in each + * input vector + * \param mapping (vector of vectors of vectors of integers) how to + * map elements from input to output vectors + */ + static sptr make(size_t item_size, std::vector<size_t> in_vlens, + std::vector< std::vector< std::vector<size_t> > > mapping); + + virtual void set_mapping(std::vector< std::vector< std::vector<size_t> > > mapping) = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_VECTOR_MAP_H */ diff --git a/gr-blocks/include/blocks/vector_sink_X.h.t b/gr-blocks/include/blocks/vector_sink_X.h.t new file mode 100644 index 0000000000..d15c795721 --- /dev/null +++ b/gr-blocks/include/blocks/vector_sink_X.h.t @@ -0,0 +1,54 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2008,2009,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. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief @TYPE@ sink that writes to a vector + * \ingroup sink_blk + */ + class BLOCKS_API @NAME@ : virtual public gr_sync_block + { + public: + // gr::blocks::@NAME@::sptr + typedef boost::shared_ptr<@NAME@> sptr; + + static sptr make(int vlen = 1); + + virtual void reset() = 0; + virtual std::vector<@TYPE@> data() const = 0; + virtual std::vector<gr_tag_t> tags() const = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-blocks/include/blocks/vector_source_X.h.t b/gr-blocks/include/blocks/vector_source_X.h.t new file mode 100644 index 0000000000..c68b638e62 --- /dev/null +++ b/gr-blocks/include/blocks/vector_source_X.h.t @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2008,2012-2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief source of @TYPE@'s that gets its data from a vector + * \ingroup source_blk + */ + class BLOCKS_API @NAME@ : virtual public gr_sync_block + { + public: + // gr::blocks::@NAME@::sptr + typedef boost::shared_ptr<@NAME@> sptr; + + static sptr make(const std::vector<@TYPE@> &data, + bool repeat=false, int vlen=1, + const std::vector<gr_tag_t> &tags=std::vector<gr_tag_t>()); + + virtual void rewind() = 0; + virtual void set_data(const std::vector<@TYPE@> &data, + const std::vector<gr_tag_t> &tags=std::vector<gr_tag_t>()) = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-blocks/lib/CMakeLists.txt b/gr-blocks/lib/CMakeLists.txt index de73a8a308..6e2b583308 100644 --- a/gr-blocks/lib/CMakeLists.txt +++ b/gr-blocks/lib/CMakeLists.txt @@ -114,6 +114,9 @@ expand_cc_h_impl(sub_XX ss ii ff cc) expand_cc_h_impl(xor_XX bb ss ii) expand_cc_h_impl(packed_to_unpacked_XX bb ss ii) expand_cc_h_impl(unpacked_to_packed_XX bb ss ii) +expand_cc_h_impl(vector_insert_X b s i f c) +expand_cc_h_impl(vector_sink_X b s i f c) +expand_cc_h_impl(vector_source_X b s i f c) ######################################################################## # Setup the include and linker paths @@ -147,6 +150,9 @@ list(APPEND gr_blocks_sources fxpt.cc wavfile.cc add_ff_impl.cc + annotator_1to1_impl.cc + annotator_alltoall_impl.cc + annotator_raw_impl.cc bin_statistics_f_impl.cc burst_tagger_impl.cc char_to_float_impl.cc @@ -159,8 +165,10 @@ list(APPEND gr_blocks_sources complex_to_mag_squared_impl.cc complex_to_arg_impl.cc conjugate_cc_impl.cc + copy_impl.cc deinterleave_impl.cc delay_impl.cc + endian_swap_impl.cc file_descriptor_sink_impl.cc file_descriptor_source_impl.cc file_sink_impl.cc @@ -174,6 +182,7 @@ list(APPEND gr_blocks_sources float_to_short_impl.cc float_array_to_uchar.cc float_to_uchar_impl.cc + head_impl.cc int_to_float_impl.cc interleave_impl.cc interleaved_short_array_to_complex.cc @@ -191,6 +200,9 @@ list(APPEND gr_blocks_sources multiply_const_cc_impl.cc multiply_const_ff_impl.cc nlog10_ff_impl.cc + nop_impl.cc + null_sink_impl.cc + null_source_impl.cc pack_k_bits_bb_impl.cc patterned_interleaver_impl.cc pdu.cc @@ -206,6 +218,7 @@ list(APPEND gr_blocks_sources rms_ff_impl.cc short_to_char_impl.cc short_to_float_impl.cc + skiphead_impl.cc socket_pdu_impl.cc stream_mux_impl.cc stream_pdu_base.cc @@ -228,6 +241,7 @@ list(APPEND gr_blocks_sources udp_source_impl.cc unpack_k_bits_bb_impl.cc vco_f_impl.cc + vector_map_impl.cc vector_to_stream_impl.cc vector_to_streams_impl.cc wavfile_sink_impl.cc @@ -268,15 +282,19 @@ GR_LIBRARY_FOO(gnuradio-blocks RUNTIME_COMPONENT "blocks_runtime" DEVEL_COMPONEN if(ENABLE_TESTING) include(GrTest) - include_directories(${CPPUNIT_INCLUDE_DIRS}) + include_directories( + ${GR_FILTER_INCLUDE_DIRS} + ${CPPUNIT_INCLUDE_DIRS}) link_directories(${CPPUNIT_LIBRARY_DIRS}) list(APPEND test_gr_blocks_sources ${CMAKE_CURRENT_SOURCE_DIR}/test_gr_blocks.cc ${CMAKE_CURRENT_SOURCE_DIR}/qa_blocks.cc + ${CMAKE_CURRENT_SOURCE_DIR}/qa_block_tags.cc ${CMAKE_CURRENT_SOURCE_DIR}/qa_fxpt.cc ${CMAKE_CURRENT_SOURCE_DIR}/qa_fxpt_nco.cc ${CMAKE_CURRENT_SOURCE_DIR}/qa_fxpt_vco.cc + ${CMAKE_CURRENT_SOURCE_DIR}/qa_rotator.cc ) add_executable(test-gr-blocks ${test_gr_blocks_sources}) @@ -287,6 +305,7 @@ if(ENABLE_TESTING) test-gr-blocks gnuradio-core gnuradio-blocks + gnuradio-filter ${Boost_LIBRARIES} ${CPPUNIT_LIBRARIES} ) diff --git a/gr-blocks/lib/annotator_1to1_impl.cc b/gr-blocks/lib/annotator_1to1_impl.cc new file mode 100644 index 0000000000..d3f4758684 --- /dev/null +++ b/gr-blocks/lib/annotator_1to1_impl.cc @@ -0,0 +1,113 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010,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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "annotator_1to1_impl.h" +#include <gr_io_signature.h> +#include <string.h> +#include <iostream> +#include <iomanip> + +namespace gr { + namespace blocks { + + annotator_1to1::sptr + annotator_1to1::make(int when, size_t sizeof_stream_item) + { + return gnuradio::get_initial_sptr + (new annotator_1to1_impl(when, sizeof_stream_item)); + } + + annotator_1to1_impl::annotator_1to1_impl(int when, size_t sizeof_stream_item) + : gr_sync_block("annotator_1to1", + gr_make_io_signature(1, -1, sizeof_stream_item), + gr_make_io_signature(1, -1, sizeof_stream_item)), + d_itemsize(sizeof_stream_item), d_when((uint64_t)when) + { + set_tag_propagation_policy(TPP_ONE_TO_ONE); + + d_tag_counter = 0; + set_relative_rate(1.0); + } + + annotator_1to1_impl::~annotator_1to1_impl() + { + } + + int + annotator_1to1_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *in = (const float*)input_items[0]; + float *out = (float*)output_items[0]; + + std::stringstream str; + str << name() << unique_id(); + + uint64_t abs_N = 0; + int ninputs = input_items.size(); + for(int i = 0; i < ninputs; i++) { + abs_N = nitems_read(i); + + std::vector<gr_tag_t> all_tags; + get_tags_in_range(all_tags, i, abs_N, abs_N + noutput_items); + + std::vector<gr_tag_t>::iterator itr; + for(itr = all_tags.begin(); itr != all_tags.end(); itr++) { + d_stored_tags.push_back(*itr); + } + } + + // Storing the current noutput_items as the value to the "noutput_items" key + pmt::pmt_t srcid = pmt::pmt_string_to_symbol(str.str()); + pmt::pmt_t key = pmt::pmt_string_to_symbol("seq"); + + // Work does nothing to the data stream; just copy all inputs to outputs + // Adds a new tag when the number of items read is a multiple of d_when + abs_N = nitems_read(0); + int noutputs = output_items.size(); + for(int j = 0; j < noutput_items; j++) { + // the min() is a hack to make sure this doesn't segfault if + // there are a different number of ins and outs. This is + // specifically designed to test the 1-to-1 propagation policy. + for(int i = 0; i < std::min(noutputs, ninputs); i++) { + if(abs_N % d_when == 0) { + pmt::pmt_t value = pmt::pmt_from_uint64(d_tag_counter++); + add_item_tag(i, abs_N, key, value, srcid); + } + + in = (const float*)input_items[i]; + out = (float*)output_items[i]; + out[j] = in[j]; + } + abs_N++; + } + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/annotator_1to1_impl.h b/gr-blocks/lib/annotator_1to1_impl.h new file mode 100644 index 0000000000..3306602e2c --- /dev/null +++ b/gr-blocks/lib/annotator_1to1_impl.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_ANNOTATOR_1TO1_IMPL_H +#define INCLUDED_GR_ANNOTATOR_1TO1_IMPL_H + +#include <blocks/annotator_1to1.h> + +namespace gr { + namespace blocks { + + class annotator_1to1_impl : public annotator_1to1 + { + private: + size_t d_itemsize; + uint64_t d_when; + uint64_t d_tag_counter; + std::vector<gr_tag_t> d_stored_tags; + + public: + annotator_1to1_impl(int when, size_t sizeof_stream_item); + ~annotator_1to1_impl(); + + std::vector<gr_tag_t> data() const + { + return d_stored_tags; + } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_ANNOTATOR_1TO1_IMPL_H */ diff --git a/gr-blocks/lib/annotator_alltoall_impl.cc b/gr-blocks/lib/annotator_alltoall_impl.cc new file mode 100644 index 0000000000..5af1a9c18e --- /dev/null +++ b/gr-blocks/lib/annotator_alltoall_impl.cc @@ -0,0 +1,117 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010,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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "annotator_alltoall_impl.h" +#include <gr_io_signature.h> +#include <string.h> +#include <iostream> +#include <iomanip> + +namespace gr { + namespace blocks { + + annotator_alltoall::sptr + annotator_alltoall::make(int when, size_t sizeof_stream_item) + { + return gnuradio::get_initial_sptr + (new annotator_alltoall_impl(when, sizeof_stream_item)); + } + + annotator_alltoall_impl::annotator_alltoall_impl(int when, + size_t sizeof_stream_item) + : gr_sync_block("annotator_alltoall", + gr_make_io_signature(1, -1, sizeof_stream_item), + gr_make_io_signature(1, -1, sizeof_stream_item)), + d_itemsize(sizeof_stream_item), d_when((uint64_t)when) + { + set_tag_propagation_policy(TPP_ALL_TO_ALL); + + d_tag_counter = 0; + } + + annotator_alltoall_impl::~annotator_alltoall_impl() + { + } + + int + annotator_alltoall_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *in = (const float*)input_items[0]; + float *out = (float*)output_items[0]; + + std::stringstream str; + str << name() << unique_id(); + + uint64_t abs_N = 0, end_N; + int ninputs = input_items.size(); + for(int i = 0; i < ninputs; i++) { + abs_N = nitems_read(i); + end_N = abs_N + (uint64_t)(noutput_items); + + std::vector<gr_tag_t> all_tags; + get_tags_in_range(all_tags, i, abs_N, end_N); + + std::vector<gr_tag_t>::iterator itr; + for(itr = all_tags.begin(); itr != all_tags.end(); itr++) { + d_stored_tags.push_back(*itr); + } + } + + // Source ID and key for any tag that might get applied from this block + pmt::pmt_t srcid = pmt::pmt_string_to_symbol(str.str()); + pmt::pmt_t key = pmt::pmt_string_to_symbol("seq"); + + // Work does nothing to the data stream; just copy all inputs to + // outputs Adds a new tag when the number of items read is a + // multiple of d_when + abs_N = nitems_written(0); + int noutputs = output_items.size(); + + for(int j = 0; j < noutput_items; j++) { + for(int i = 0; i < noutputs; i++) { + if(abs_N % d_when == 0) { + pmt::pmt_t value = pmt::pmt_from_uint64(d_tag_counter++); + add_item_tag(i, abs_N, key, value, srcid); + } + + // Sum all of the inputs together for each output. Just 'cause. + out = (float*)output_items[i]; + out[j] = 0; + for(int ins = 0; ins < ninputs; ins++) { + in = (const float*)input_items[ins]; + out[j] += in[j]; + } + } + abs_N++; + } + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/annotator_alltoall_impl.h b/gr-blocks/lib/annotator_alltoall_impl.h new file mode 100644 index 0000000000..24c21948bc --- /dev/null +++ b/gr-blocks/lib/annotator_alltoall_impl.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_ANNOTATOR_ALLTOALL_IMPL_H +#define INCLUDED_GR_ANNOTATOR_ALLTOALL_IMPL_H + +#include <blocks/annotator_alltoall.h> + +namespace gr { + namespace blocks { + + class annotator_alltoall_impl : public annotator_alltoall + { + private: + size_t d_itemsize; + uint64_t d_when; + uint64_t d_tag_counter; + std::vector<gr_tag_t> d_stored_tags; + + public: + annotator_alltoall_impl(int when, size_t sizeof_stream_item); + ~annotator_alltoall_impl(); + + std::vector<gr_tag_t> data() const + { + return d_stored_tags; + } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_ANNOTATOR_ALLTOALL_IMPL_H */ diff --git a/gr-blocks/lib/annotator_raw_impl.cc b/gr-blocks/lib/annotator_raw_impl.cc new file mode 100644 index 0000000000..1b92523089 --- /dev/null +++ b/gr-blocks/lib/annotator_raw_impl.cc @@ -0,0 +1,112 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010,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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "annotator_raw_impl.h" +#include <gr_io_signature.h> +#include <string.h> +#include <iostream> +#include <iomanip> +#include <stdexcept> + +using namespace pmt; + +namespace gr { + namespace blocks { + + annotator_raw::sptr + annotator_raw::make(size_t sizeof_stream_item) + { + return gnuradio::get_initial_sptr + (new annotator_raw_impl(sizeof_stream_item)); + } + + annotator_raw_impl::annotator_raw_impl(size_t sizeof_stream_item) + : gr_sync_block("annotator_raw", + gr_make_io_signature(1, 1, sizeof_stream_item), + gr_make_io_signature(1, 1, sizeof_stream_item)), + d_itemsize(sizeof_stream_item) + { + set_tag_propagation_policy(TPP_ONE_TO_ONE); + set_relative_rate(1.0); + } + + void annotator_raw_impl::add_tag(uint64_t offset, pmt_t key, pmt_t val) + { + gruel::scoped_lock l(d_mutex); + + gr_tag_t tag; + tag.srcid = pmt::pmt_intern(name()); + tag.key = key; + tag.value = val; + tag.offset = offset; + + // add our new tag + d_queued_tags.push_back(tag); + // make sure our tags are in offset order + std::sort(d_queued_tags.begin(), d_queued_tags.end(), + gr_tag_t::offset_compare); + // make sure we are not adding an item in the past! + if(tag.offset > nitems_read(0)) { + throw std::runtime_error("annotator_raw::add_tag: item added too far in the past\n."); + } + } + + annotator_raw_impl::~annotator_raw_impl() + { + } + + int + annotator_raw_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + gruel::scoped_lock l(d_mutex); + + const char *in = (const char*)input_items[0]; + char *out = (char*)output_items[0]; + + uint64_t start_N = nitems_read(0); + uint64_t end_N = start_N + (uint64_t)(noutput_items); + + // locate queued tags that fall in this range and insert them when appropriate + std::vector<gr_tag_t>::iterator i = d_queued_tags.begin(); + while( i != d_queued_tags.end() ) { + if( (*i).offset >= start_N && (*i).offset < end_N) { + add_item_tag(0, (*i).offset,(*i).key, (*i).value, (*i).srcid); + i = d_queued_tags.erase(i); + } + else { + break; + } + } + + // copy data across + memcpy(out, in, noutput_items*d_itemsize); + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/annotator_raw_impl.h b/gr-blocks/lib/annotator_raw_impl.h new file mode 100644 index 0000000000..2e349bfe33 --- /dev/null +++ b/gr-blocks/lib/annotator_raw_impl.h @@ -0,0 +1,54 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_ANNOTATOR_RAW_IMPL_H +#define INCLUDED_GR_ANNOTATOR_RAW_IMPL_H + +#include <blocks/annotator_raw.h> +#include <gruel/thread.h> + +namespace gr { + namespace blocks { + + class annotator_raw_impl : public annotator_raw + { + private: + size_t d_itemsize; + std::vector<gr_tag_t> d_queued_tags; + gruel::mutex d_mutex; + + public: + annotator_raw_impl(size_t sizeof_stream_item); + ~annotator_raw_impl(); + + // insert a tag to be added + void add_tag(uint64_t offset, pmt::pmt_t key, pmt::pmt_t val); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_ANNOTATOR_RAW_IMPL_H */ diff --git a/gr-blocks/lib/copy_impl.cc b/gr-blocks/lib/copy_impl.cc new file mode 100644 index 0000000000..929f22b7d3 --- /dev/null +++ b/gr-blocks/lib/copy_impl.cc @@ -0,0 +1,91 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2009,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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "copy_impl.h" +#include <gr_io_signature.h> +#include <string.h> + +namespace gr { + namespace blocks { + + copy::sptr + copy::make(size_t itemsize) + { + return gnuradio::get_initial_sptr + (new copy_impl(itemsize)); + } + + copy_impl::copy_impl(size_t itemsize) + : gr_block("copy", + gr_make_io_signature(1, -1, itemsize), + gr_make_io_signature(1, -1, itemsize)), + d_itemsize(itemsize), + d_enabled(true) + { + } + + copy_impl::~copy_impl() + { + } + + void + copy_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) + { + unsigned ninputs = ninput_items_required.size(); + for (unsigned i = 0; i < ninputs; i++) + ninput_items_required[i] = noutput_items; + } + + bool + copy_impl::check_topology(int ninputs, int noutputs) + { + return ninputs == noutputs; + } + + int + copy_impl::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const uint8_t **in = (const uint8_t**)&input_items[0]; + uint8_t **out = (uint8_t**)&output_items[0]; + + int n = 0; + if(d_enabled) { + int ninputs = input_items.size(); + for(int i = 0; i < ninputs; i++) { + memcpy(out[i], in[i], noutput_items*d_itemsize); + } + n = noutput_items; + } + + consume_each(noutput_items); + return n; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/copy_impl.h b/gr-blocks/lib/copy_impl.h new file mode 100644 index 0000000000..1f0f1a655e --- /dev/null +++ b/gr-blocks/lib/copy_impl.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2009,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_COPY_IMPL_H +#define INCLUDED_GR_COPY_IMPL_H + +#include <blocks/copy.h> + +namespace gr { + namespace blocks { + + class copy_impl : public copy + { + private: + size_t d_itemsize; + bool d_enabled; + + public: + copy_impl(size_t itemsize); + ~copy_impl(); + + void forecast(int noutput_items, gr_vector_int &ninput_items_required); + bool check_topology(int ninputs, int noutputs); + + void set_enabled(bool enable) { d_enabled = enable; } + bool enabled() const { return d_enabled;} + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_COPY_IMPL_H */ diff --git a/gr-blocks/lib/endian_swap_impl.cc b/gr-blocks/lib/endian_swap_impl.cc new file mode 100644 index 0000000000..7e67c30147 --- /dev/null +++ b/gr-blocks/lib/endian_swap_impl.cc @@ -0,0 +1,110 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,2012,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "endian_swap_impl.h" +#include <gr_io_signature.h> +#include <volk/volk.h> + +namespace gr { + namespace blocks { + + endian_swap::sptr + endian_swap::make(size_t item_size_bytes) + { + return gnuradio::get_initial_sptr + (new endian_swap_impl(item_size_bytes)); + } + + endian_swap_impl::endian_swap_impl (size_t item_size_bytes) + : gr_sync_block("endian_swap_impl", + gr_make_io_signature(1, 1, item_size_bytes), + gr_make_io_signature(1, 1, item_size_bytes)) + { + const int alignment_multiple = volk_get_alignment(); + set_alignment(std::max(1, alignment_multiple)); + } + + endian_swap_impl::~endian_swap_impl() + { + } + + int + endian_swap_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const char *in = (const char*)input_items[0]; + char *out = (char*)output_items[0]; + + int nbytes(output_signature()->sizeof_stream_item(0)); + if(is_unaligned()) { + switch(nbytes){ + case 1: + memcpy(out,in,noutput_items); + break; + case 2: + memcpy(out,in,2*noutput_items); + volk_16u_byteswap_u((uint16_t*)out,noutput_items); + break; + case 4: + memcpy(out,in,4*noutput_items); + volk_32u_byteswap_u((uint32_t*)out,noutput_items); + break; + case 8: + memcpy(out,in,8*noutput_items); + volk_64u_byteswap_u((uint64_t*)out,noutput_items); + break; + default: + throw std::runtime_error("itemsize is not valid for endian_swap!"); + } + } + else { + switch(nbytes) { + case 1: + memcpy(out,in,noutput_items); + break; + case 2: + memcpy(out,in,2*noutput_items); + volk_16u_byteswap_a((uint16_t*)out,noutput_items); + break; + case 4: + memcpy(out,in,4*noutput_items); + volk_32u_byteswap_a((uint32_t*)out,noutput_items); + break; + case 8: + memcpy(out,in,8*noutput_items); + volk_64u_byteswap_a((uint64_t*)out,noutput_items); + break; + default: + throw std::runtime_error("itemsize is not valid for endian_swap!"); + } + } + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/endian_swap_impl.h b/gr-blocks/lib/endian_swap_impl.h new file mode 100644 index 0000000000..517df44f17 --- /dev/null +++ b/gr-blocks/lib/endian_swap_impl.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_ENDIAN_SWAP_IMPL_H +#define INCLUDED_GR_ENDIAN_SWAP_IMPL_H + +#include <blocks/endian_swap.h> + +namespace gr { + namespace blocks { + + class endian_swap_impl : public endian_swap + { + private: + size_t item_size_bytes; + + public: + endian_swap_impl(size_t item_size_bytes); + ~endian_swap_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_ENDIAN_SWAP_IMPL_H */ diff --git a/gr-blocks/lib/head_impl.cc b/gr-blocks/lib/head_impl.cc new file mode 100644 index 0000000000..7dfa36607c --- /dev/null +++ b/gr-blocks/lib/head_impl.cc @@ -0,0 +1,75 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "head_impl.h" +#include <gr_io_signature.h> +#include <string.h> + +namespace gr { + namespace blocks { + + head::sptr + head::make(size_t sizeof_stream_item, uint64_t nitems) + { + return gnuradio::get_initial_sptr + (new head_impl(sizeof_stream_item, nitems)); + } + + head_impl::head_impl(size_t sizeof_stream_item, uint64_t nitems) + : gr_sync_block("head", + gr_make_io_signature(1, 1, sizeof_stream_item), + gr_make_io_signature(1, 1, sizeof_stream_item)), + d_nitems(nitems), d_ncopied_items(0) + { + } + + head_impl::~head_impl() + { + } + + int + head_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + if(d_ncopied_items >= d_nitems) + return -1; // Done! + + unsigned n = std::min(d_nitems - d_ncopied_items, + (uint64_t)noutput_items); + + if(n == 0) + return 0; + + memcpy(output_items[0], input_items[0], + n * input_signature()->sizeof_stream_item (0)); + d_ncopied_items += n; + + return n; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/head_impl.h b/gr-blocks/lib/head_impl.h new file mode 100644 index 0000000000..a56acfbb27 --- /dev/null +++ b/gr-blocks/lib/head_impl.h @@ -0,0 +1,52 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2012,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_HEAD_IMPL_H +#define INCLUDED_GR_HEAD_IMPL_H + +#include <blocks/head.h> + +namespace gr { + namespace blocks { + + class head_impl : public head + { + private: + uint64_t d_nitems; + uint64_t d_ncopied_items; + + public: + head_impl(size_t sizeof_stream_item, uint64_t nitems); + ~head_impl(); + + void reset() { d_ncopied_items = 0; } + void set_length(int nitems) { d_nitems = nitems; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_HEAD_IMPL_H */ diff --git a/gr-blocks/lib/nop_impl.cc b/gr-blocks/lib/nop_impl.cc new file mode 100644 index 0000000000..766f07e2b8 --- /dev/null +++ b/gr-blocks/lib/nop_impl.cc @@ -0,0 +1,78 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "nop_impl.h" +#include <gr_io_signature.h> +#include <boost/bind.hpp> + +namespace gr { + namespace blocks { + + nop::sptr + nop::make(size_t sizeof_stream_item) + { + return gnuradio::get_initial_sptr + (new nop_impl(sizeof_stream_item)); + } + + nop_impl::nop_impl (size_t sizeof_stream_item) + : gr_block("nop", + gr_make_io_signature(0, -1, sizeof_stream_item), + gr_make_io_signature(0, -1, sizeof_stream_item)), + d_nmsgs_recvd(0) + { + // Arrange to have count_received_msgs called when messages are received. + message_port_register_in(pmt::mp("port")); + set_msg_handler(pmt::mp("port"), boost::bind(&nop_impl::count_received_msgs, this, _1)); + } + + nop_impl::~nop_impl() + { + } + + // Trivial message handler that just counts them. + // (N.B., This feature is used in qa_set_msg_handler) + void + nop_impl::count_received_msgs(pmt::pmt_t msg) + { + d_nmsgs_recvd++; + } + + int + nop_impl::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + // eat any input that's available + for(unsigned i = 0; i < ninput_items.size (); i++) + consume(i, ninput_items[i]); + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/nop_impl.h b/gr-blocks/lib/nop_impl.h new file mode 100644 index 0000000000..b236abb7aa --- /dev/null +++ b/gr-blocks/lib/nop_impl.h @@ -0,0 +1,54 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_NOP_IMPL_H +#define INCLUDED_GR_NOP_IMPL_H + +#include <blocks/nop.h> + +namespace gr { + namespace blocks { + + class nop_impl : public nop + { + protected: + int d_nmsgs_recvd; + + // Method that just counts any received messages. + void count_received_msgs(pmt::pmt_t msg); + + public: + nop_impl(size_t sizeof_stream_item); + ~nop_impl(); + + int nmsgs_received() const { return d_nmsgs_recvd; } + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_NOP_IMPL_H */ diff --git a/gr-blocks/lib/null_sink_impl.cc b/gr-blocks/lib/null_sink_impl.cc new file mode 100644 index 0000000000..b780a2405a --- /dev/null +++ b/gr-blocks/lib/null_sink_impl.cc @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "null_sink_impl.h" +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + null_sink::sptr + null_sink::make(size_t sizeof_stream_item) + { + return gnuradio::get_initial_sptr + (new null_sink_impl(sizeof_stream_item)); + } + + null_sink_impl::null_sink_impl(size_t sizeof_stream_item) + : gr_sync_block("null_sink", + gr_make_io_signature(1, 1, sizeof_stream_item), + gr_make_io_signature(0, 0, 0)) + { + } + + null_sink_impl::~null_sink_impl() + { + } + + int + null_sink_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/null_sink_impl.h b/gr-blocks/lib/null_sink_impl.h new file mode 100644 index 0000000000..bb4c695c23 --- /dev/null +++ b/gr-blocks/lib/null_sink_impl.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_NULL_SINK_IMPL_H +#define INCLUDED_GR_NULL_SINK_IMPL_H + +#include <blocks/null_sink.h> + +namespace gr { + namespace blocks { + + class null_sink_impl : public null_sink + { + public: + null_sink_impl(size_t sizeof_stream_item); + ~null_sink_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_NULL_SINK_IMPL_H */ diff --git a/gr-blocks/lib/null_source_impl.cc b/gr-blocks/lib/null_source_impl.cc new file mode 100644 index 0000000000..81999d0501 --- /dev/null +++ b/gr-blocks/lib/null_source_impl.cc @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "null_source_impl.h" +#include <gr_io_signature.h> +#include <string.h> + +namespace gr { + namespace blocks { + + null_source::sptr + null_source::make(size_t sizeof_stream_item) + { + return gnuradio::get_initial_sptr + (new null_source_impl(sizeof_stream_item)); + } + + null_source_impl::null_source_impl (size_t sizeof_stream_item) + : gr_sync_block("null_source", + gr_make_io_signature(0, 0, 0), + gr_make_io_signature(1, 1, sizeof_stream_item)) + { + } + + null_source_impl::~null_source_impl() + { + } + + int + null_source_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + void *optr = (void*)output_items[0]; + memset(optr, 0, noutput_items * output_signature()->sizeof_stream_item(0)); + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/null_source_impl.h b/gr-blocks/lib/null_source_impl.h new file mode 100644 index 0000000000..36201d54b6 --- /dev/null +++ b/gr-blocks/lib/null_source_impl.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_NULL_SOURCE_IMPL_H +#define INCLUDED_GR_NULL_SOURCE_IMPL_H + +#include <blocks/null_source.h> + +namespace gr { + namespace blocks { + + class null_source_impl : public null_source + { + public: + null_source_impl(size_t sizeof_stream_item); + ~null_source_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_NULL_SOURCE_IMPL_H */ diff --git a/gr-blocks/lib/qa_block_tags.cc b/gr-blocks/lib/qa_block_tags.cc new file mode 100644 index 0000000000..93edc4695a --- /dev/null +++ b/gr-blocks/lib/qa_block_tags.cc @@ -0,0 +1,451 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010,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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <qa_block_tags.h> +#include <gr_block.h> +#include <gr_top_block.h> +#include <gr_null_source.h> +#include <gr_null_sink.h> +#include <gr_head.h> +#include <blocks/annotator_alltoall.h> +#include <blocks/annotator_1to1.h> +#include <gr_keep_one_in_n.h> +#include <filter/firdes.h> +#include <gr_tags.h> + + +// ---------------------------------------------------------------- + +using namespace pmt; + +// set to 1 to turn on debug output +// The debug output fully checks that the tags seen are what are expected. While +// this behavior currently works with our implementation, there is no guarentee +// that the tags will be coming in this specific order, so it's dangerous to +// rely on this as a test of the tag system working. We would really want to +// tags we know we should see and then test that they all occur once, but in no +// particular order. +#define QA_TAGS_DEBUG 0 + +void +qa_block_tags::t0() +{ + unsigned int N = 1000; + gr_top_block_sptr tb = gr_make_top_block("top"); + gr_block_sptr src (gr_make_null_source(sizeof(int))); + gr_block_sptr head (gr_make_head(sizeof(int), N)); + gr_block_sptr snk (gr_make_null_sink(sizeof(int))); + + tb->connect(src, 0, head, 0); + tb->connect(head, 0, snk, 0); + + //CPPUNIT_ASSERT_THROW(src->nitems_read(0), std::runtime_error); + //CPPUNIT_ASSERT_THROW(src->nitems_written(0), std::runtime_error); + CPPUNIT_ASSERT_EQUAL(src->nitems_read(0), (uint64_t)0); + CPPUNIT_ASSERT_EQUAL(src->nitems_written(0), (uint64_t)0); + + tb->run(); + + CPPUNIT_ASSERT_THROW(src->nitems_read(0), std::invalid_argument); + CPPUNIT_ASSERT(src->nitems_written(0) >= N); + CPPUNIT_ASSERT_EQUAL(snk->nitems_read(0), (uint64_t)1000); + CPPUNIT_ASSERT_THROW(snk->nitems_written(0), std::invalid_argument); +} + + +void +qa_block_tags::t1() +{ + int N = 40000; + gr_top_block_sptr tb = gr_make_top_block("top"); + gr_block_sptr src (gr_make_null_source(sizeof(int))); + gr_block_sptr head (gr_make_head(sizeof(int), N)); + gr::blocks::annotator_alltoall::sptr ann0(gr::blocks::annotator_alltoall::make(10000, sizeof(int))); + gr::blocks::annotator_alltoall::sptr ann1(gr::blocks::annotator_alltoall::make(10000, sizeof(int))); + gr::blocks::annotator_alltoall::sptr ann2(gr::blocks::annotator_alltoall::make(10000, sizeof(int))); + gr::blocks::annotator_alltoall::sptr ann3(gr::blocks::annotator_alltoall::make(10000, sizeof(int))); + gr::blocks::annotator_alltoall::sptr ann4(gr::blocks::annotator_alltoall::make(10000, sizeof(int))); + gr_block_sptr snk0 (gr_make_null_sink(sizeof(int))); + gr_block_sptr snk1 (gr_make_null_sink(sizeof(int))); + + tb->connect(src, 0, head, 0); + tb->connect(head, 0, ann0, 0); + + tb->connect(ann0, 0, ann1, 0); + tb->connect(ann0, 1, ann2, 0); + tb->connect(ann1, 0, ann3, 0); + tb->connect(ann2, 0, ann4, 0); + + tb->connect(ann3, 0, snk0, 0); + tb->connect(ann4, 0, snk1, 0); + + tb->run(); + + std::vector<gr_tag_t> tags0 = ann0->data(); + std::vector<gr_tag_t> tags3 = ann3->data(); + std::vector<gr_tag_t> tags4 = ann4->data(); + + // The first annotator does not receive any tags from the null sink upstream + CPPUNIT_ASSERT_EQUAL(tags0.size(), (size_t)0); + CPPUNIT_ASSERT_EQUAL(tags3.size(), (size_t)8); + CPPUNIT_ASSERT_EQUAL(tags4.size(), (size_t)8); + +#if QA_TAGS_DEBUG + // Kludge together the tags that we know should result from the above graph + std::stringstream str0, str1, str2; + str0 << ann0->name() << ann0->unique_id(); + str1 << ann1->name() << ann1->unique_id(); + str2 << ann2->name() << ann2->unique_id(); + + pmt_t expected_tags3[8]; + expected_tags3[0] = mp(pmt_from_uint64(0), mp(str1.str()), mp("seq"), mp(0)); + expected_tags3[1] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(0)); + expected_tags3[2] = mp(pmt_from_uint64(10000), mp(str1.str()), mp("seq"), mp(1)); + expected_tags3[3] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(2)); + expected_tags3[4] = mp(pmt_from_uint64(20000), mp(str1.str()), mp("seq"), mp(2)); + expected_tags3[5] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(4)); + expected_tags3[6] = mp(pmt_from_uint64(30000), mp(str1.str()), mp("seq"), mp(3)); + expected_tags3[7] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(6)); + + pmt_t expected_tags4[8]; + expected_tags4[0] = mp(pmt_from_uint64(0), mp(str2.str()), mp("seq"), mp(0)); + expected_tags4[1] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(1)); + expected_tags4[2] = mp(pmt_from_uint64(10000), mp(str2.str()), mp("seq"), mp(1)); + expected_tags4[3] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(3)); + expected_tags4[4] = mp(pmt_from_uint64(20000), mp(str2.str()), mp("seq"), mp(2)); + expected_tags4[5] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(5)); + expected_tags4[6] = mp(pmt_from_uint64(30000), mp(str2.str()), mp("seq"), mp(3)); + expected_tags4[7] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(7)); + + std::cout << std::endl << "qa_block_tags::t1" << std::endl; + + // For annotator 3, we know it gets tags from ann0 and ann1, test this + for(size_t i = 0; i < tags3.size(); i++) { + std::cout << "tags3[" << i << "] = " << tags3[i] << "\t\t" << expected_tags3[i] << std::endl; + CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags3[i]), pmt_write_string(expected_tags3[i])); + } + + // For annotator 4, we know it gets tags from ann0 and ann2, test this + std::cout << std::endl; + for(size_t i = 0; i < tags4.size(); i++) { + std::cout << "tags4[" << i << "] = " << tags4[i] << "\t\t" << expected_tags4[i] << std::endl; + CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags4[i]), pmt_write_string(expected_tags4[i])); + } +#endif +} + +void +qa_block_tags::t2 () +{ + int N = 40000; + gr_top_block_sptr tb = gr_make_top_block("top"); + gr_block_sptr src (gr_make_null_source(sizeof(int))); + gr_block_sptr head (gr_make_head(sizeof(int), N)); + gr::blocks::annotator_alltoall::sptr ann0(gr::blocks::annotator_alltoall::make(10000, sizeof(int))); + gr::blocks::annotator_alltoall::sptr ann1(gr::blocks::annotator_alltoall::make(10000, sizeof(int))); + gr::blocks::annotator_alltoall::sptr ann2(gr::blocks::annotator_alltoall::make(10000, sizeof(int))); + gr::blocks::annotator_alltoall::sptr ann3(gr::blocks::annotator_alltoall::make(10000, sizeof(int))); + gr::blocks::annotator_alltoall::sptr ann4(gr::blocks::annotator_alltoall::make(10000, sizeof(int))); + gr_block_sptr snk0 (gr_make_null_sink(sizeof(int))); + gr_block_sptr snk1 (gr_make_null_sink(sizeof(int))); + gr_block_sptr snk2 (gr_make_null_sink(sizeof(int))); + + tb->connect(src, 0, head, 0); + tb->connect(head, 0, ann0, 0); + + tb->connect(ann0, 0, ann1, 0); + tb->connect(ann0, 1, ann1, 1); + tb->connect(ann1, 0, ann2, 0); + tb->connect(ann1, 1, ann3, 0); + tb->connect(ann1, 2, ann4, 0); + + tb->connect(ann2, 0, snk0, 0); + tb->connect(ann3, 0, snk1, 0); + tb->connect(ann4, 0, snk2, 0); + + tb->run(); + + std::vector<gr_tag_t> tags0 = ann0->data(); + std::vector<gr_tag_t> tags1 = ann1->data(); + std::vector<gr_tag_t> tags2 = ann2->data(); + std::vector<gr_tag_t> tags3 = ann4->data(); + std::vector<gr_tag_t> tags4 = ann4->data(); + + // The first annotator does not receive any tags from the null sink upstream + CPPUNIT_ASSERT_EQUAL(tags0.size(), (size_t)0); + CPPUNIT_ASSERT_EQUAL(tags1.size(), (size_t)8); + + // Make sure the rest all have 12 tags + CPPUNIT_ASSERT_EQUAL(tags2.size(), (size_t)12); + CPPUNIT_ASSERT_EQUAL(tags3.size(), (size_t)12); + CPPUNIT_ASSERT_EQUAL(tags4.size(), (size_t)12); + + +#if QA_TAGS_DEBUG + // Kludge together the tags that we know should result from the above graph + std::stringstream str0, str1; + str0 << ann0->name() << ann0->unique_id(); + str1 << ann1->name() << ann1->unique_id(); + + pmt_t expected_tags2[12]; + expected_tags2[0] = mp(pmt_from_uint64(0), mp(str1.str()), mp("seq"), mp(0)); + expected_tags2[1] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(0)); + expected_tags2[2] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(1)); + expected_tags2[3] = mp(pmt_from_uint64(10000), mp(str1.str()), mp("seq"), mp(3)); + expected_tags2[4] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(2)); + expected_tags2[5] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(3)); + expected_tags2[6] = mp(pmt_from_uint64(20000), mp(str1.str()), mp("seq"), mp(6)); + expected_tags2[7] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(4)); + expected_tags2[8] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(5)); + expected_tags2[9] = mp(pmt_from_uint64(30000), mp(str1.str()), mp("seq"), mp(9)); + expected_tags2[10] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(6)); + expected_tags2[11] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(7)); + + pmt_t expected_tags4[12]; + expected_tags4[0] = mp(pmt_from_uint64(0), mp(str1.str()), mp("seq"), mp(2)); + expected_tags4[1] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(0)); + expected_tags4[2] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(1)); + expected_tags4[3] = mp(pmt_from_uint64(10000), mp(str1.str()), mp("seq"), mp(5)); + expected_tags4[4] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(2)); + expected_tags4[5] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(3)); + expected_tags4[6] = mp(pmt_from_uint64(20000), mp(str1.str()), mp("seq"), mp(8)); + expected_tags4[7] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(4)); + expected_tags4[8] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(5)); + expected_tags4[9] = mp(pmt_from_uint64(30000), mp(str1.str()), mp("seq"), mp(11)); + expected_tags4[10] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(6)); + expected_tags4[11] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(7)); + + std::cout << std::endl << "qa_block_tags::t2" << std::endl; + + // For annotator[2-4], we know it gets tags from ann0 and ann1 + // but the tags from the different outputs of ann1 are different for each. + // Just testing ann2 and ann4; if they are correct it would be + // inconceivable for ann3 to have it wrong. + for(size_t i = 0; i < tags2.size(); i++) { + std::cout << "tags2[" << i << "] = " << tags2[i] << "\t\t" << expected_tags2[i] << std::endl; + CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags2[i]), pmt_write_string(expected_tags2[i])); + } + + std::cout << std::endl; + for(size_t i = 0; i < tags4.size(); i++) { + std::cout << "tags2[" << i << "] = " << tags4[i] << "\t\t" << expected_tags4[i] << std::endl; + CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags4[i]), pmt_write_string(expected_tags4[i])); + } +#endif +} + + +void +qa_block_tags::t3() +{ + int N = 40000; + gr_top_block_sptr tb = gr_make_top_block("top"); + gr_block_sptr src (gr_make_null_source(sizeof(int))); + gr_block_sptr head (gr_make_head(sizeof(int), N)); + gr::blocks::annotator_1to1::sptr ann0 (gr::blocks::annotator_1to1::make(10000, sizeof(int))); + gr::blocks::annotator_alltoall::sptr ann1 (gr::blocks::annotator_alltoall::make(10000, sizeof(int))); + gr::blocks::annotator_alltoall::sptr ann2 (gr::blocks::annotator_alltoall::make(10000, sizeof(int))); + gr::blocks::annotator_1to1::sptr ann3 (gr::blocks::annotator_1to1::make(10000, sizeof(int))); + gr::blocks::annotator_1to1::sptr ann4 (gr::blocks::annotator_1to1::make(10000, sizeof(int))); + gr_block_sptr snk0 (gr_make_null_sink(sizeof(int))); + gr_block_sptr snk1 (gr_make_null_sink(sizeof(int))); + + tb->connect(src, 0, head, 0); + tb->connect(head, 0, ann0, 0); + tb->connect(head, 0, ann0, 1); + + tb->connect(ann0, 0, ann1, 0); + tb->connect(ann0, 1, ann2, 0); + tb->connect(ann1, 0, ann3, 0); + tb->connect(ann2, 0, ann4, 0); + + tb->connect(ann3, 0, snk0, 0); + tb->connect(ann4, 0, snk1, 0); + + tb->run(); + + + std::vector<gr_tag_t> tags0 = ann0->data(); + std::vector<gr_tag_t> tags3 = ann3->data(); + std::vector<gr_tag_t> tags4 = ann4->data(); + + // The first annotator does not receive any tags from the null sink upstream + CPPUNIT_ASSERT_EQUAL(tags0.size(), (size_t)0); + CPPUNIT_ASSERT_EQUAL(tags3.size(), (size_t)8); + CPPUNIT_ASSERT_EQUAL(tags4.size(), (size_t)8); + +#if QA_TAGS_DEBUG + // Kludge together the tags that we know should result from the above graph + std::stringstream str0, str1, str2; + str0 << ann0->name() << ann0->unique_id(); + str1 << ann1->name() << ann1->unique_id(); + str2 << ann2->name() << ann2->unique_id(); + + pmt_t expected_tags3[8]; + expected_tags3[0] = mp(pmt_from_uint64(0), mp(str1.str()), mp("seq"), mp(0)); + expected_tags3[1] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(0)); + expected_tags3[2] = mp(pmt_from_uint64(10000), mp(str1.str()), mp("seq"), mp(1)); + expected_tags3[3] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(2)); + expected_tags3[4] = mp(pmt_from_uint64(20000), mp(str1.str()), mp("seq"), mp(2)); + expected_tags3[5] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(4)); + expected_tags3[6] = mp(pmt_from_uint64(30000), mp(str1.str()), mp("seq"), mp(3)); + expected_tags3[7] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(6)); + + pmt_t expected_tags4[8]; + expected_tags4[0] = mp(pmt_from_uint64(0), mp(str2.str()), mp("seq"), mp(0)); + expected_tags4[1] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(1)); + expected_tags4[2] = mp(pmt_from_uint64(10000), mp(str2.str()), mp("seq"), mp(1)); + expected_tags4[3] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(3)); + expected_tags4[4] = mp(pmt_from_uint64(20000), mp(str2.str()), mp("seq"), mp(2)); + expected_tags4[5] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(5)); + expected_tags4[6] = mp(pmt_from_uint64(30000), mp(str2.str()), mp("seq"), mp(3)); + expected_tags4[7] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(7)); + + std::cout << std::endl << "qa_block_tags::t3" << std::endl; + + // For annotator 3, we know it gets tags from ann0 and ann1, test this + for(size_t i = 0; i < tags3.size(); i++) { + std::cout << "tags3[" << i << "] = " << tags3[i] << "\t\t" << expected_tags3[i] << std::endl; + CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags3[i]), pmt_write_string(expected_tags3[i])); + } + + // For annotator 4, we know it gets tags from ann0 and ann2, test this + std::cout << std::endl; + for(size_t i = 0; i < tags4.size(); i++) { + std::cout << "tags4[" << i << "] = " << tags4[i] << "\t\t" << expected_tags4[i] << std::endl; + CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags4[i]), pmt_write_string(expected_tags4[i])); + } +#endif +} + + +void +qa_block_tags::t4() +{ + int N = 40000; + gr_top_block_sptr tb = gr_make_top_block("top"); + gr_block_sptr src (gr_make_null_source(sizeof(int))); + gr_block_sptr head (gr_make_head(sizeof(int), N)); + gr::blocks::annotator_1to1::sptr ann0(gr::blocks::annotator_1to1::make(10000, sizeof(int))); + gr::blocks::annotator_1to1::sptr ann1(gr::blocks::annotator_1to1::make(10000, sizeof(int))); + gr::blocks::annotator_1to1::sptr ann2(gr::blocks::annotator_1to1::make(10000, sizeof(int))); + gr_block_sptr snk0 (gr_make_null_sink(sizeof(int))); + gr_block_sptr snk1 (gr_make_null_sink(sizeof(int))); + + // using 1-to-1 tag propagation without having equal number of + // ins and outs. Make sure this works; will just exit run early. + tb->connect(src, 0, head, 0); + tb->connect(head, 0, ann0, 0); + tb->connect(ann0, 0, ann1, 0); + tb->connect(ann0, 1, ann2, 0); + tb->connect(ann1, 0, snk0, 0); + tb->connect(ann2, 0, snk1, 0); + + std::cerr << std::endl + << "NOTE: This is supposed to produce an error from gr_block_executor" + << std::endl; + tb->run(); +} + + +void +qa_block_tags::t5() +{ + int N = 40000; + gr_top_block_sptr tb = gr_make_top_block("top"); + gr_block_sptr src (gr_make_null_source(sizeof(float))); + gr_block_sptr head (gr_make_head(sizeof(float), N)); + gr::blocks::annotator_alltoall::sptr ann0(gr::blocks::annotator_alltoall::make(10000, sizeof(float))); + gr::blocks::annotator_alltoall::sptr ann1(gr::blocks::annotator_alltoall::make(10000, sizeof(float))); + gr::blocks::annotator_alltoall::sptr ann2(gr::blocks::annotator_alltoall::make(1000, sizeof(float))); + gr_block_sptr snk0 (gr_make_null_sink(sizeof(float))); + + // Rate change blocks + gr_keep_one_in_n_sptr dec10 (gr_make_keep_one_in_n(sizeof(float), 10)); + + tb->connect(src, 0, head, 0); + tb->connect(head, 0, ann0, 0); + tb->connect(ann0, 0, ann1, 0); + tb->connect(ann1, 0, dec10, 0); + tb->connect(dec10, 0, ann2, 0); + tb->connect(ann2, 0, snk0, 0); + + tb->run(); + + std::vector<gr_tag_t> tags0 = ann0->data(); + std::vector<gr_tag_t> tags1 = ann1->data(); + std::vector<gr_tag_t> tags2 = ann2->data(); + + // The first annotator does not receive any tags from the null sink upstream + CPPUNIT_ASSERT_EQUAL(tags0.size(), (size_t)0); + CPPUNIT_ASSERT_EQUAL(tags1.size(), (size_t)4); + CPPUNIT_ASSERT_EQUAL(tags2.size(), (size_t)8); + + +#if QA_TAGS_DEBUG + // Kludge together the tags that we know should result from the above graph + std::stringstream str0, str1, str2; + str0 << ann0->name() << ann0->unique_id(); + str1 << ann1->name() << ann1->unique_id(); + str2 << ann2->name() << ann2->unique_id(); + + pmt_t expected_tags1[5]; + expected_tags1[0] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(0)); + expected_tags1[1] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(1)); + expected_tags1[2] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(2)); + expected_tags1[3] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(3)); + + pmt_t expected_tags2[10]; + expected_tags2[0] = mp(pmt_from_uint64(0), mp(str1.str()), mp("seq"), mp(0)); + expected_tags2[1] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(0)); + expected_tags2[2] = mp(pmt_from_uint64(1000), mp(str1.str()), mp("seq"), mp(1)); + expected_tags2[3] = mp(pmt_from_uint64(1000), mp(str0.str()), mp("seq"), mp(1)); + expected_tags2[4] = mp(pmt_from_uint64(2000), mp(str1.str()), mp("seq"), mp(2)); + expected_tags2[5] = mp(pmt_from_uint64(2000), mp(str0.str()), mp("seq"), mp(2)); + expected_tags2[6] = mp(pmt_from_uint64(3000), mp(str1.str()), mp("seq"), mp(3)); + expected_tags2[7] = mp(pmt_from_uint64(3000), mp(str0.str()), mp("seq"), mp(3)); + expected_tags2[8] = mp(pmt_from_uint64(4000), mp(str1.str()), mp("seq"), mp(4)); + expected_tags2[9] = mp(pmt_from_uint64(4000), mp(str0.str()), mp("seq"), mp(4)); + + std::cout << std::endl << "qa_block_tags::t5" << std::endl; + + // annotator 1 gets tags from annotator 0 + std::cout << "tags1.size(): " << tags1.size() << std::endl; + for(size_t i = 0; i < tags1.size(); i++) { + std::cout << "tags1[" << i << "] = " << tags1[i] << "\t\t" << expected_tags1[i] << std::endl; + CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags1[i]), pmt_write_string(expected_tags1[i])); + } + + // annotator 2 gets tags from annotators 0 and 1 + std::cout << std::endl; + std::cout << "tags2.size(): " << tags2.size() << std::endl; + for(size_t i = 0; i < tags2.size(); i++) { + std::cout << "tags2[" << i << "] = " << tags2[i] << "\t\t" << expected_tags2[i] << std::endl; + CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags2[i]), pmt_write_string(expected_tags2[i])); + } +#endif +} + diff --git a/gr-blocks/lib/qa_block_tags.h b/gr-blocks/lib/qa_block_tags.h new file mode 100644 index 0000000000..83bebe23f6 --- /dev/null +++ b/gr-blocks/lib/qa_block_tags.h @@ -0,0 +1,50 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_QA_BLOCK_TAGS_H +#define INCLUDED_QA_BLOCK_TAGS_H + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> +#include <stdexcept> + +class qa_block_tags : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(qa_block_tags); + CPPUNIT_TEST(t0); + CPPUNIT_TEST(t1); + CPPUNIT_TEST(t2); + CPPUNIT_TEST(t3); + CPPUNIT_TEST(t4); + CPPUNIT_TEST(t5); + CPPUNIT_TEST_SUITE_END(); + + private: + void t0(); + void t1(); + void t2(); + void t3(); + void t4(); + void t5(); +}; + +#endif /* INCLUDED_QA_BLOCK_TAGS_H */ diff --git a/gr-blocks/lib/qa_blocks.cc b/gr-blocks/lib/qa_blocks.cc index fbae11d264..ebf5d3c349 100644 --- a/gr-blocks/lib/qa_blocks.cc +++ b/gr-blocks/lib/qa_blocks.cc @@ -26,18 +26,22 @@ */ #include <qa_blocks.h> +#include <qa_block_tags.h> #include <qa_fxpt.h> #include <qa_fxpt_nco.h> #include <qa_fxpt_vco.h> +#include <qa_rotator.h> CppUnit::TestSuite * qa_gr_blocks::suite() { CppUnit::TestSuite *s = new CppUnit::TestSuite("gr-blocks"); + s->addTest(qa_block_tags::suite()); s->addTest(qa_fxpt::suite()); s->addTest(qa_fxpt_nco::suite()); s->addTest(qa_fxpt_vco::suite()); + s->addTest(qa_rotator::suite()); return s; } diff --git a/gr-blocks/lib/qa_rotator.cc b/gr-blocks/lib/qa_rotator.cc new file mode 100644 index 0000000000..86bbdd5282 --- /dev/null +++ b/gr-blocks/lib/qa_rotator.cc @@ -0,0 +1,75 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gruel/attributes.h> +#include <cppunit/TestAssert.h> +#include <qa_rotator.h> +#include <blocks/rotator.h> +#include <stdio.h> +#include <cmath> +#include <gr_expj.h> + +// error vector magnitude +__GR_ATTR_UNUSED static float +error_vector_mag(gr_complex a, gr_complex b) +{ + return abs(a-b); +} + +void +qa_rotator::t1() +{ + static const unsigned int N = 100000; + + gr::blocks::rotator r; + + double phase_incr = 2*M_PI / 1003; + double phase = 0; + + // Old code: We increment then return the rotated value, thus we + // need to start one tick back r.set_phase(gr_complex(1,0) * + // conj(gr_expj(phase_incr))); + + r.set_phase(gr_complex(1,0)); + r.set_phase_incr(gr_expj(phase_incr)); + + for(unsigned i = 0; i < N; i++) { + gr_complex expected = gr_expj(phase); + gr_complex actual = r.rotate(gr_complex(1, 0)); + +#if 0 + float evm = error_vector_mag(expected, actual); + printf("[%6d] expected: (%8.6f, %8.6f) actual: (%8.6f, %8.6f) evm: %8.6f\n", + i, expected.real(), expected.imag(), actual.real(), actual.imag(), evm); +#endif + + CPPUNIT_ASSERT_COMPLEXES_EQUAL(expected, actual, 0.0001); + + phase += phase_incr; + if(phase >= 2*M_PI) + phase -= 2*M_PI; + } +} diff --git a/gr-blocks/lib/qa_rotator.h b/gr-blocks/lib/qa_rotator.h new file mode 100644 index 0000000000..575ea506c7 --- /dev/null +++ b/gr-blocks/lib/qa_rotator.h @@ -0,0 +1,39 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _QA_GR_ROTATOR_H_ +#define _QA_GR_ROTATOR_H_ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> + +class qa_rotator : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(qa_rotator); + CPPUNIT_TEST(t1); + CPPUNIT_TEST_SUITE_END(); + + private: + void t1(); +}; + +#endif /* _QA_GR_ROTATOR_H_ */ diff --git a/gr-blocks/lib/skiphead_impl.cc b/gr-blocks/lib/skiphead_impl.cc new file mode 100644 index 0000000000..feb39eb8f4 --- /dev/null +++ b/gr-blocks/lib/skiphead_impl.cc @@ -0,0 +1,93 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2007,2010,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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "skiphead_impl.h" +#include <gr_io_signature.h> +#include <string.h> + +namespace gr { + namespace blocks { + + skiphead::sptr + skiphead::make(size_t itemsize, uint64_t nitems_to_skip) + { + return gnuradio::get_initial_sptr + (new skiphead_impl(itemsize, nitems_to_skip)); + } + + skiphead_impl::skiphead_impl(size_t itemsize, uint64_t nitems_to_skip) + : gr_block("skiphead", + gr_make_io_signature(1, 1, itemsize), + gr_make_io_signature(1, 1, itemsize)), + d_nitems_to_skip(nitems_to_skip), d_nitems(0) + { + } + + skiphead_impl::~skiphead_impl() + { + } + + int + skiphead_impl::general_work(int noutput_items, + gr_vector_int &ninput_items_, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const char *in = (const char*)input_items[0]; + char *out = (char*)output_items[0]; + + int ninput_items = std::min(ninput_items_[0], noutput_items); + int ii = 0; // input index + + while (ii < ninput_items) { + uint64_t ni_total = ii + d_nitems; // total items processed so far + if(ni_total < d_nitems_to_skip) { // need to skip some more + + int n_to_skip = (int)std::min(d_nitems_to_skip - ni_total, + (uint64_t)(ninput_items - ii)); + ii += n_to_skip; + } + + else { // nothing left to skip. copy away + int n_to_copy = ninput_items - ii; + if(n_to_copy > 0) { + size_t itemsize = output_signature()->sizeof_stream_item(0); + memcpy(out, in + (ii*itemsize), n_to_copy*itemsize); + } + + d_nitems += ninput_items; + consume_each(ninput_items); + return n_to_copy; + } + } + + d_nitems += ninput_items; + consume_each(ninput_items); + return 0; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/skiphead_impl.h b/gr-blocks/lib/skiphead_impl.h new file mode 100644 index 0000000000..d8e0870cb1 --- /dev/null +++ b/gr-blocks/lib/skiphead_impl.h @@ -0,0 +1,50 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_SKIPHEAD_IMPL_H +#define INCLUDED_GR_SKIPHEAD_IMPL_H + +#include <blocks/skiphead.h> + +namespace gr { + namespace blocks { + + class skiphead_impl : public skiphead + { + private: + uint64_t d_nitems_to_skip; + uint64_t d_nitems; // total items seen + + public: + skiphead_impl(size_t itemsize, uint64_t nitems_to_skip); + ~skiphead_impl(); + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_SKIPHEAD_IMPL_H */ diff --git a/gr-blocks/lib/vector_insert_X_impl.cc.t b/gr-blocks/lib/vector_insert_X_impl.cc.t new file mode 100644 index 0000000000..adf31fe05a --- /dev/null +++ b/gr-blocks/lib/vector_insert_X_impl.cc.t @@ -0,0 +1,109 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <@NAME_IMPL@.h> +#include <algorithm> +#include <gr_io_signature.h> +#include <stdexcept> +#include <stdio.h> + +namespace gr { + namespace blocks { + + @NAME@::sptr + @NAME@::make(const std::vector<@TYPE@> &data, int periodicity, int offset) + { + return gnuradio::get_initial_sptr + (new @NAME_IMPL@(data, periodicity, offset)); + } + + @NAME_IMPL@::@NAME_IMPL@(const std::vector<@TYPE@> &data, + int periodicity, int offset) + : gr_block("@BASE_NAME@", + gr_make_io_signature(1, 1, sizeof(@TYPE@)), + gr_make_io_signature(1, 1, sizeof(@TYPE@))), + d_data(data), + d_offset(offset), + d_periodicity(periodicity) + { + //printf("INITIAL: periodicity = %d, offset = %d\n", periodicity, offset); + // some sanity checks + assert(offset < periodicity); + assert(offset >= 0); + assert((size_t)periodicity > data.size()); + } + + @NAME_IMPL@::~@NAME_IMPL@() + {} + + int + @NAME_IMPL@::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + @TYPE@ *out = (@TYPE@ *)output_items[0]; + const @TYPE@ *in = (const @TYPE@ *)input_items[0]; + + int ii(0), oo(0); + + while((oo < noutput_items) && (ii < ninput_items[0])) { + //printf("oo = %d, ii = %d, d_offset = %d, noutput_items = %d, ninput_items[0] = %d", oo, ii, d_offset, noutput_items, ninput_items[0]); + //printf(", d_periodicity = %d\n", d_periodicity); + + if(d_offset >= ((int)d_data.size())) { // if we are in the copy region + int max_copy = std::min(std::min(noutput_items - oo, ninput_items[0] - ii), + d_periodicity - d_offset); + //printf("copy %d from input\n", max_copy); + memcpy( &out[oo], &in[ii], sizeof(@TYPE@)*max_copy ); + //printf(" * memcpy returned.\n"); + ii += max_copy; + oo += max_copy; + d_offset = (d_offset + max_copy)%d_periodicity; + } + else { // if we are in the insertion region + int max_copy = std::min(noutput_items - oo, ((int)d_data.size()) - d_offset); + //printf("copy %d from d_data[%d] to out[%d]\n", max_copy, d_offset, oo); + memcpy(&out[oo], &d_data[d_offset], sizeof(@TYPE@)*max_copy); + //printf(" * memcpy returned.\n"); + oo += max_copy; + d_offset = (d_offset + max_copy)%d_periodicity; + //printf(" ## (inelse) oo = %d, d_offset = %d\n", oo, d_offset); + } + + //printf(" # exit else, on to next loop.\n"); + } + //printf(" # got out of loop\n"); + + //printf("consume = %d, produce = %d\n", ii, oo); + consume_each(ii); + return oo; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/vector_insert_X_impl.h.t b/gr-blocks/lib/vector_insert_X_impl.h.t new file mode 100644 index 0000000000..f447ef1e80 --- /dev/null +++ b/gr-blocks/lib/vector_insert_X_impl.h.t @@ -0,0 +1,58 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME_IMPL@ +#define @GUARD_NAME_IMPL@ + +#include <blocks/@NAME@.h> + +namespace gr { + namespace blocks { + + class @NAME_IMPL@ : public @NAME@ + { + private: + std::vector<@TYPE@> d_data; + int d_offset; + int d_periodicity; + + public: + @NAME_IMPL@(const std::vector<@TYPE@> &data, + int periodicity, int offset); + ~@NAME_IMPL@(); + + void rewind() { d_offset=0; } + void set_data(const std::vector<@TYPE@> &data) { + d_data = data; rewind(); } + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME_IMPL@ */ diff --git a/gr-blocks/lib/vector_map_impl.cc b/gr-blocks/lib/vector_map_impl.cc new file mode 100644 index 0000000000..cefaaeea35 --- /dev/null +++ b/gr-blocks/lib/vector_map_impl.cc @@ -0,0 +1,127 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "vector_map_impl.h" +#include <gr_io_signature.h> +#include <string.h> + +namespace gr { + namespace blocks { + + std::vector<int> + get_in_sizeofs(size_t item_size, std::vector<size_t> in_vlens) + { + std::vector<int> in_sizeofs; + for(unsigned int i = 0; i < in_vlens.size(); i++) { + in_sizeofs.push_back(in_vlens[i]*item_size); + } + return in_sizeofs; + } + + std::vector<int> + get_out_sizeofs(size_t item_size, + std::vector< std::vector< std::vector<size_t> > > mapping) + { + std::vector<int> out_sizeofs; + for(unsigned int i = 0; i < mapping.size(); i++) { + out_sizeofs.push_back(mapping[i].size()*item_size); + } + return out_sizeofs; + } + + vector_map::sptr + vector_map::make(size_t item_size, std::vector<size_t> in_vlens, + std::vector< std::vector< std::vector<size_t> > > mapping) + { + return gnuradio::get_initial_sptr + (new vector_map_impl(item_size, in_vlens, mapping)); + } + + vector_map_impl::vector_map_impl(size_t item_size, std::vector<size_t> in_vlens, + std::vector< std::vector< std::vector<size_t> > > mapping) + : gr_sync_block("vector_map", + gr_make_io_signaturev(in_vlens.size(), in_vlens.size(), + get_in_sizeofs(item_size, in_vlens)), + gr_make_io_signaturev(mapping.size(), mapping.size(), + get_out_sizeofs(item_size, mapping))), + d_item_size(item_size), d_in_vlens(in_vlens) + { + set_mapping(mapping); + } + + vector_map_impl::~vector_map_impl() + { + } + + void + vector_map_impl::set_mapping(std::vector< std::vector< std::vector<size_t> > > mapping) + { + // Make sure the contents of the mapping vectors are possible. + for(unsigned int i=0; i<mapping.size(); i++) { + for(unsigned int j=0; j<mapping[i].size(); j++) { + if(mapping[i][j].size() != 2) { + throw std::runtime_error("Mapping must be of the form (out_mapping_stream1, out_mapping_stream2, ...), where out_mapping_stream1 is of the form (mapping_element1, mapping_element2, ...), where mapping_element1 is of the form (input_stream, input_element). This error is raised because a mapping_element vector does not contain exactly 2 items."); + } + unsigned int s = mapping[i][j][0]; + unsigned int index = mapping[i][j][1]; + if(s >= d_in_vlens.size()) { + throw std::runtime_error("Stream numbers in mapping must be less than the number of input streams."); + } + if((index < 0) || (index >= d_in_vlens[s])) { + throw std::runtime_error ("Indices in mapping must be greater than 0 and less than the input vector lengths."); + } + } + } + gruel::scoped_lock guard(d_mutex); + d_mapping = mapping; + } + + int + vector_map_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const char **inv = (const char**)&input_items[0]; + char **outv = (char**)&output_items[0]; + + for(unsigned int n = 0; n < (unsigned int)(noutput_items); n++) { + for(unsigned int i = 0; i < d_mapping.size(); i++) { + unsigned int out_vlen = d_mapping[i].size(); + for(unsigned int j = 0; j < out_vlen; j++) { + unsigned int s = d_mapping[i][j][0]; + unsigned int k = d_mapping[i][j][1]; + memcpy(outv[i] + out_vlen*d_item_size*n + + d_item_size*j, inv[s] + d_in_vlens[s]*d_item_size*n + + k*d_item_size, d_item_size); + } + } + } + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/vector_map_impl.h b/gr-blocks/lib/vector_map_impl.h new file mode 100644 index 0000000000..e27b3b9cec --- /dev/null +++ b/gr-blocks/lib/vector_map_impl.h @@ -0,0 +1,55 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_VECTOR_MAP_IMPL_H +#define INCLUDED_GR_VECTOR_MAP_IMPL_H + +#include <blocks/vector_map.h> +#include <gruel/thread.h> + +namespace gr { + namespace blocks { + + class vector_map_impl : public vector_map + { + private: + size_t d_item_size; + std::vector<size_t> d_in_vlens; + std::vector< std::vector< std::vector<size_t> > > d_mapping; + gruel::mutex d_mutex; // mutex to protect set/work access + + public: + vector_map_impl(size_t item_size, std::vector<size_t> in_vlens, + std::vector< std::vector< std::vector<size_t> > > mapping); + ~vector_map_impl(); + + void set_mapping(std::vector< std::vector< std::vector<size_t> > > mapping); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_VECTOR_MAP_IMPL_H */ diff --git a/gr-blocks/lib/vector_sink_X_impl.cc.t b/gr-blocks/lib/vector_sink_X_impl.cc.t new file mode 100644 index 0000000000..3be2861025 --- /dev/null +++ b/gr-blocks/lib/vector_sink_X_impl.cc.t @@ -0,0 +1,83 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2008,2010,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. + */ + +// @WARNING@ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <@NAME_IMPL@.h> +#include <gr_io_signature.h> +#include <algorithm> +#include <iostream> + +namespace gr { + namespace blocks { + + @NAME@::sptr + @BASE_NAME@::make(int vlen) + { + return gnuradio::get_initial_sptr + (new @NAME_IMPL@(vlen)); + } + + @NAME_IMPL@::@NAME_IMPL@(int vlen) + : gr_sync_block("@NAME@", + gr_make_io_signature(1, 1, sizeof(@TYPE@) * vlen), + gr_make_io_signature(0, 0, 0)), + d_vlen(vlen) + { + } + + @NAME_IMPL@::~@NAME_IMPL@() + {} + + std::vector<@TYPE@> + @NAME_IMPL@::data() const + { + return d_data; + } + + std::vector<gr_tag_t> + @NAME_IMPL@::tags() const + { + return d_tags; + } + + int + @NAME_IMPL@::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + @TYPE@ *iptr = (@TYPE@*)input_items[0]; + + for(int i = 0; i < noutput_items * d_vlen; i++) + d_data.push_back (iptr[i]); + std::vector<gr_tag_t> tags; + get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0) + noutput_items); + d_tags.insert(d_tags.end(), tags.begin(), tags.end()); + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/vector_sink_X_impl.h.t b/gr-blocks/lib/vector_sink_X_impl.h.t new file mode 100644 index 0000000000..60d21e0c8c --- /dev/null +++ b/gr-blocks/lib/vector_sink_X_impl.h.t @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2008,2009,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. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME_IMPL@ +#define @GUARD_NAME_IMPL@ + +#include <blocks/@NAME@.h> + +namespace gr { + namespace blocks { + + class @NAME_IMPL@ : public @NAME@ + { + private: + std::vector<@TYPE@> d_data; + std::vector<gr_tag_t> d_tags; + int d_vlen; + + public: + @NAME_IMPL@(int vlen); + ~@NAME_IMPL@(); + + void reset() { d_data.clear(); } + std::vector<@TYPE@> data() const; + std::vector<gr_tag_t> tags() const; + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME_IMPL@ */ diff --git a/gr-blocks/lib/vector_source_X_impl.cc.t b/gr-blocks/lib/vector_source_X_impl.cc.t new file mode 100644 index 0000000000..9c1c63a213 --- /dev/null +++ b/gr-blocks/lib/vector_source_X_impl.cc.t @@ -0,0 +1,144 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2008,2010,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. + */ + +// @WARNING@ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <@NAME_IMPL@.h> +#include <algorithm> +#include <gr_io_signature.h> +#include <stdexcept> + +namespace gr { + namespace blocks { + + @NAME@::sptr + @NAME@::make(const std::vector<@TYPE@> &data, + bool repeat, int vlen, + const std::vector<gr_tag_t> &tags) + { + return gnuradio::get_initial_sptr + (new @NAME_IMPL@(data, repeat, vlen, tags)); + } + + @NAME_IMPL@::@NAME_IMPL@(const std::vector<@TYPE@> &data, + bool repeat, int vlen, + const std::vector<gr_tag_t> &tags) + : gr_sync_block("@BASE_NAME@", + gr_make_io_signature(0, 0, 0), + gr_make_io_signature(1, 1, sizeof(@TYPE@) * vlen)), + d_data(data), + d_repeat(repeat), + d_offset(0), + d_vlen(vlen), + d_tags(tags), + d_tagpos(0) + { + if(tags.size() == 0) { + d_settags = 0; + } + else { + d_settags = 1; + set_output_multiple(data.size() / vlen); + } + if((data.size() % vlen) != 0) + throw std::invalid_argument("data length must be a multiple of vlen"); + } + + @NAME_IMPL@::~@NAME_IMPL@() + {} + + void + @NAME_IMPL@::set_data (const std::vector<@TYPE@> &data, + const std::vector<gr_tag_t> &tags) + { + d_data = data; + d_tags = tags; + rewind(); + if(tags.size() == 0) { + d_settags = false; + } + else { + d_settags = true; + } + } + + int + @NAME_IMPL@::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + @TYPE@ *optr = (@TYPE@ *) output_items[0]; + + if(d_repeat) { + unsigned int size = d_data.size (); + unsigned int offset = d_offset; + if(size == 0) + return -1; + + if(d_settags) { + int n_outputitems_per_vector = d_data.size() / d_vlen; + for(int i = 0; i < noutput_items; i += n_outputitems_per_vector) { + // FIXME do proper vector copy + memcpy((void *) optr, (const void*)&d_data[0], size*sizeof (@TYPE@)); + 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); + } + } + } + else { + for(int i = 0; i < noutput_items*d_vlen; i++) { + optr[i] = d_data[offset++]; + if(offset >= size) { + offset = 0; + } + } + } + + d_offset = offset; + return noutput_items; + } + else { + if(d_offset >= d_data.size ()) + return -1; // Done! + + unsigned n = std::min((unsigned)d_data.size() - d_offset, + (unsigned)noutput_items*d_vlen); + for(unsigned i = 0; i < n; i++) { + optr[i] = d_data[d_offset + i]; + } + for(unsigned t = 0; t < d_tags.size(); t++) { + if((d_tags[t].offset >= d_offset) && (d_tags[t].offset < d_offset+n)) + add_item_tag(0, d_tags[t].offset, d_tags[t].key, d_tags[t].value); + } + d_offset += n; + return n/d_vlen; + } + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/vector_source_X_impl.h.t b/gr-blocks/lib/vector_source_X_impl.h.t new file mode 100644 index 0000000000..78ec52bacf --- /dev/null +++ b/gr-blocks/lib/vector_source_X_impl.h.t @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2008,2012-2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME_IMPL@ +#define @GUARD_NAME_IMPL@ + +#include <blocks/@NAME@.h> + +namespace gr { + namespace blocks { + + class @NAME_IMPL@ : public @NAME@ + { + private: + std::vector<@TYPE@> d_data; + bool d_repeat; + unsigned int d_offset; + int d_vlen; + bool d_settags; + std::vector<gr_tag_t> d_tags; + unsigned int d_tagpos; + + public: + @NAME_IMPL@(const std::vector<@TYPE@> &data, + bool repeat, int vlen, + const std::vector<gr_tag_t> &tags); + ~@NAME_IMPL@(); + + void rewind() { d_offset=0; } + void set_data(const std::vector<@TYPE@> &data, + const std::vector<gr_tag_t> &tags); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME_IMPL@ */ diff --git a/gr-blocks/python/qa_copy.py b/gr-blocks/python/qa_copy.py new file mode 100755 index 0000000000..012d790609 --- /dev/null +++ b/gr-blocks/python/qa_copy.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +# +# Copyright 2009,2010,2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import blocks_swig as blocks + +class test_copy(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_copy(self): + src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + expected_result = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + src = blocks.vector_source_b(src_data) + op = blocks.copy(gr.sizeof_char) + dst = blocks.vector_sink_b() + self.tb.connect(src, op, dst) + self.tb.run() + dst_data = dst.data() + self.assertEqual(expected_result, dst_data) + + def test_copy_drop (self): + src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + expected_result = () + src = blocks.vector_source_b(src_data) + op = gr.copy(gr.sizeof_char) + op.set_enabled(False) + dst = blocks.vector_sink_b() + self.tb.connect(src, op, dst) + self.tb.run() + dst_data = dst.data() + self.assertEqual(expected_result, dst_data) + +if __name__ == '__main__': + gr_unittest.run(test_copy, "test_copy.xml") diff --git a/gr-blocks/python/qa_endian_swap.py b/gr-blocks/python/qa_endian_swap.py new file mode 100644 index 0000000000..5180293052 --- /dev/null +++ b/gr-blocks/python/qa_endian_swap.py @@ -0,0 +1,66 @@ +#!/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. +# + +from gnuradio import gr, gr_unittest +import blocks_swig as blocks +import ctypes + +class test_endian_swap(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_001(self): + src_data = [1,2,3,4] + expected_result = [256, 512, 768, 1024]; + + src = blocks.vector_source_s(src_data) + op = blocks.endian_swap(2) + dst = blocks.vector_sink_s() + + self.tb.connect(src, op, dst) + self.tb.run() + result_data = list(dst.data()) + + self.assertEqual(expected_result, result_data) + + def test_002(self): + + src_data = [1,2,3,4] + expected_result = [16777216, 33554432, 50331648, 67108864]; + + src = blocks.vector_source_i(src_data) + op = blocks.endian_swap(4) + dst = blocks.vector_sink_i() + + self.tb.connect(src, op, dst) + self.tb.run() + result_data = list(dst.data()) + + self.assertEqual(expected_result, result_data) + +if __name__ == '__main__': + gr_unittest.run(test_endian_swap, "test_endian_swap.xml") + diff --git a/gr-blocks/python/qa_head.py b/gr-blocks/python/qa_head.py new file mode 100755 index 0000000000..39b1255978 --- /dev/null +++ b/gr-blocks/python/qa_head.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python +# +# Copyright 2004,2007,2010,2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import blocks_swig as blocks + +class test_head(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_head(self): + src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + expected_result = (1, 2, 3, 4) + src1 = blocks.vector_source_i(src_data) + op = blocks.head(gr.sizeof_int, 4) + dst1 = blocks.vector_sink_i() + self.tb.connect(src1, op) + self.tb.connect(op, dst1) + self.tb.run() + dst_data = dst1.data() + self.assertEqual(expected_result, dst_data) + +if __name__ == '__main__': + gr_unittest.run(test_head, "test_head.xml") diff --git a/gr-blocks/python/qa_null_sink_source.py b/gr-blocks/python/qa_null_sink_source.py new file mode 100644 index 0000000000..60552cb207 --- /dev/null +++ b/gr-blocks/python/qa_null_sink_source.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +# +# Copyright 2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import blocks_swig as blocks +import math + +class test_null_sink_source(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_001(self): + # Just running some data through null source/sink + src = blocks.null_source(gr.sizeof_float) + hed = blocks.head(gr.sizeof_float, 100) + dst = blocks.null_sink(gr.sizeof_float) + + self.tb.connect(src, hed, dst) + self.tb.run() + +if __name__ == '__main__': + gr_unittest.run(test_null_sink_source, "test_null_sink_source.xml") + diff --git a/gr-blocks/python/qa_skiphead.py b/gr-blocks/python/qa_skiphead.py new file mode 100755 index 0000000000..50a9bbc639 --- /dev/null +++ b/gr-blocks/python/qa_skiphead.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# +# Copyright 2007,2010,2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import blocks_swig as blocks + +class test_skiphead(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + self.src_data = [int(x) for x in range(65536)] + + def tearDown(self): + self.tb = None + + def test_skip_0(self): + skip_cnt = 0 + expected_result = tuple(self.src_data[skip_cnt:]) + src1 = blocks.vector_source_i(self.src_data) + op = blocks.skiphead(gr.sizeof_int, skip_cnt) + dst1 = blocks.vector_sink_i() + self.tb.connect(src1, op, dst1) + self.tb.run() + dst_data = dst1.data() + self.assertEqual(expected_result, dst_data) + + def test_skip_1(self): + skip_cnt = 1 + expected_result = tuple(self.src_data[skip_cnt:]) + src1 = blocks.vector_source_i(self.src_data) + op = blocks.skiphead(gr.sizeof_int, skip_cnt) + dst1 = blocks.vector_sink_i() + self.tb.connect(src1, op, dst1) + self.tb.run() + dst_data = dst1.data() + self.assertEqual(expected_result, dst_data) + + def test_skip_1023(self): + skip_cnt = 1023 + expected_result = tuple(self.src_data[skip_cnt:]) + src1 = blocks.vector_source_i(self.src_data) + op = blocks.skiphead(gr.sizeof_int, skip_cnt) + dst1 = blocks.vector_sink_i() + self.tb.connect(src1, op, dst1) + self.tb.run() + dst_data = dst1.data() + self.assertEqual(expected_result, dst_data) + + def test_skip_6339(self): + skip_cnt = 6339 + expected_result = tuple(self.src_data[skip_cnt:]) + src1 = blocks.vector_source_i(self.src_data) + op = blocks.skiphead(gr.sizeof_int, skip_cnt) + dst1 = blocks.vector_sink_i() + self.tb.connect(src1, op, dst1) + self.tb.run() + dst_data = dst1.data() + self.assertEqual(expected_result, dst_data) + + def test_skip_12678(self): + skip_cnt = 12678 + expected_result = tuple(self.src_data[skip_cnt:]) + src1 = blocks.vector_source_i(self.src_data) + op = blocks.skiphead(gr.sizeof_int, skip_cnt) + dst1 = blocks.vector_sink_i() + self.tb.connect(src1, op, dst1) + self.tb.run() + dst_data = dst1.data() + self.assertEqual(expected_result, dst_data) + + def test_skip_all(self): + skip_cnt = len(self.src_data) + expected_result = tuple(self.src_data[skip_cnt:]) + src1 = blocks.vector_source_i(self.src_data) + op = blocks.skiphead(gr.sizeof_int, skip_cnt) + dst1 = blocks.vector_sink_i() + self.tb.connect(src1, op, dst1) + self.tb.run() + dst_data = dst1.data() + self.assertEqual(expected_result, dst_data) + + +if __name__ == '__main__': + gr_unittest.run(test_skiphead, "test_skiphead.xml") diff --git a/gr-blocks/python/qa_vector_insert.py b/gr-blocks/python/qa_vector_insert.py new file mode 100755 index 0000000000..428a0031ba --- /dev/null +++ b/gr-blocks/python/qa_vector_insert.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +# +# Copyright 2012-2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import blocks_swig as blocks +import math + +class test_vector_insert(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_001(self): + src_data = [float(x) for x in range(16)] + expected_result = tuple(src_data) + + period = 9177; + offset = 0; + + src = gr.null_source(1) + head = gr.head(1, 10000000); + ins = blocks.vector_insert_b([1], period, offset); + dst = blocks.vector_sink_b() + + self.tb.connect(src, head, ins, dst) + self.tb.run() + result_data = dst.data() + + for i in range(10000): + if(i%period == offset): + self.assertEqual(1, result_data[i]) + else: + self.assertEqual(0, result_data[i]) + +if __name__ == '__main__': + gr_unittest.run(test_vector_insert, "test_vector_insert.xml") + diff --git a/gr-blocks/python/qa_vector_map.py b/gr-blocks/python/qa_vector_map.py new file mode 100644 index 0000000000..54565fe443 --- /dev/null +++ b/gr-blocks/python/qa_vector_map.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python +# +# Copyright 2012,2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import blocks_swig as blocks +import math + +class test_vector_map(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_reversing(self): + # Chunk data in blocks of N and reverse the block contents. + N = 5 + src_data = range(0, 20) + expected_result = [] + for i in range(N-1, len(src_data), N): + for j in range(0, N): + expected_result.append(1.0*(i-j)) + mapping = [list(reversed([(0, i) for i in range(0, N)]))] + src = blocks.vector_source_f(src_data, False, N) + vmap = blocks.vector_map(gr.sizeof_float, (N, ), mapping) + dst = blocks.vector_sink_f(N) + self.tb.connect(src, vmap, dst) + self.tb.run() + result_data = list(dst.data()) + self.assertEqual(expected_result, result_data) + + def test_vector_to_streams(self): + # Split an input vector into N streams. + N = 5 + M = 20 + src_data = range(0, M) + expected_results = [] + for n in range(0, N): + expected_results.append(range(n, M, N)) + mapping = [[(0, n)] for n in range(0, N)] + src = blocks.vector_source_f(src_data, False, N) + vmap = blocks.vector_map(gr.sizeof_float, (N, ), mapping) + dsts = [blocks.vector_sink_f(1) for n in range(0, N)] + self.tb.connect(src, vmap) + for n in range(0, N): + self.tb.connect((vmap, n), dsts[n]) + self.tb.run() + for n in range(0, N): + result_data = list(dsts[n].data()) + self.assertEqual(expected_results[n], result_data) + + def test_interleaving(self): + # Takes 3 streams (a, b and c) + # Outputs 2 streams. + # First (d) is interleaving of a and b. + # Second (e) is interleaving of a and b and c. c is taken in + # chunks of 2 which are reversed. + A = (1, 2, 3, 4, 5) + B = (11, 12, 13, 14, 15) + C = (99, 98, 97, 96, 95, 94, 93, 92, 91, 90) + expected_D = (1, 11, 2, 12, 3, 13, 4, 14, 5, 15) + expected_E = (1, 11, 98, 99, 2, 12, 96, 97, 3, 13, 94, 95, + 4, 14, 92, 93, 5, 15, 90, 91) + mapping = [[(0, 0), (1, 0)], # mapping to produce D + [(0, 0), (1, 0), (2, 1), (2, 0)], # mapping to produce E + ] + srcA = blocks.vector_source_f(A, False, 1) + srcB = blocks.vector_source_f(B, False, 1) + srcC = blocks.vector_source_f(C, False, 2) + vmap = blocks.vector_map(gr.sizeof_int, (1, 1, 2), mapping) + dstD = blocks.vector_sink_f(2) + dstE = blocks.vector_sink_f(4) + self.tb.connect(srcA, (vmap, 0)) + self.tb.connect(srcB, (vmap, 1)) + self.tb.connect(srcC, (vmap, 2)) + self.tb.connect((vmap, 0), dstD) + self.tb.connect((vmap, 1), dstE) + self.tb.run() + self.assertEqual(expected_D, dstD.data()) + self.assertEqual(expected_E, dstE.data()) + +if __name__ == '__main__': + gr_unittest.run(test_vector_map, "test_vector_map.xml") + diff --git a/gr-blocks/python/qa_vector_sink_source.py b/gr-blocks/python/qa_vector_sink_source.py new file mode 100755 index 0000000000..169e6a4450 --- /dev/null +++ b/gr-blocks/python/qa_vector_sink_source.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python +# +# Copyright 2008,2010,2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import blocks_swig as blocks +import math + +class test_vector_sink_source(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_001(self): + src_data = [float(x) for x in range(16)] + expected_result = tuple(src_data) + + src = blocks.vector_source_f(src_data) + dst = blocks.vector_sink_f() + + self.tb.connect(src, dst) + self.tb.run() + result_data = dst.data() + self.assertEqual(expected_result, result_data) + + def test_002(self): + src_data = [float(x) for x in range(16)] + expected_result = tuple(src_data) + + src = blocks.vector_source_f(src_data, False, 2) + dst = blocks.vector_sink_f(2) + + self.tb.connect(src, dst) + self.tb.run() + result_data = dst.data() + self.assertEqual(expected_result, result_data) + + def test_003(self): + src_data = [float(x) for x in range(16)] + expected_result = tuple(src_data) + self.assertRaises(RuntimeError, lambda : blocks.vector_source_f(src_data, False, 3)) + +if __name__ == '__main__': + gr_unittest.run(test_vector_sink_source, "test_vector_sink_source.xml") + diff --git a/gr-blocks/swig/blocks_swig.i b/gr-blocks/swig/blocks_swig.i index 5245721b68..8d5d0c0114 100644 --- a/gr-blocks/swig/blocks_swig.i +++ b/gr-blocks/swig/blocks_swig.i @@ -30,6 +30,9 @@ %include <gr_endianness.h> +%template() std::vector<size_t>; +%template() std::vector< std::vector< std::vector<size_t> > >; + %{ #include "blocks/add_ff.h" #include "blocks/add_ss.h" @@ -67,12 +70,14 @@ #include "blocks/complex_to_arg.h" #include "blocks/conjugate_cc.h" #include "blocks/control_loop.h" +#include "blocks/copy.h" #include "blocks/deinterleave.h" #include "blocks/delay.h" #include "blocks/divide_ff.h" #include "blocks/divide_ss.h" #include "blocks/divide_ii.h" #include "blocks/divide_cc.h" +#include "blocks/endian_swap.h" #include "blocks/file_descriptor_sink.h" #include "blocks/file_descriptor_source.h" #include "blocks/file_sink_base.h" @@ -85,6 +90,7 @@ #include "blocks/float_to_int.h" #include "blocks/float_to_short.h" #include "blocks/float_to_uchar.h" +#include "blocks/head.h" #include "blocks/int_to_float.h" #include "blocks/integrate_ss.h" #include "blocks/integrate_ii.h" @@ -124,9 +130,12 @@ #include "blocks/mute_ff.h" #include "blocks/mute_cc.h" #include "blocks/nlog10_ff.h" +#include "blocks/nop.h" #include "blocks/not_bb.h" #include "blocks/not_ss.h" #include "blocks/not_ii.h" +#include "blocks/null_sink.h" +#include "blocks/null_source.h" #include "blocks/patterned_interleaver.h" #include "blocks/pack_k_bits_bb.h" #include "blocks/packed_to_unpacked_bb.h" @@ -163,6 +172,7 @@ #include "blocks/sample_and_hold_ff.h" #include "blocks/short_to_char.h" #include "blocks/short_to_float.h" +#include "blocks/skiphead.h" #include "blocks/socket_pdu.h" #include "blocks/stream_mux.h" #include "blocks/stream_to_streams.h" @@ -190,8 +200,24 @@ #include "blocks/unpacked_to_packed_ss.h" #include "blocks/unpacked_to_packed_ii.h" #include "blocks/vco_f.h" +#include "blocks/vector_map.h" #include "blocks/vector_to_stream.h" #include "blocks/vector_to_streams.h" +#include "blocks/vector_insert_b.h" +#include "blocks/vector_insert_s.h" +#include "blocks/vector_insert_i.h" +#include "blocks/vector_insert_f.h" +#include "blocks/vector_insert_c.h" +#include "blocks/vector_sink_b.h" +#include "blocks/vector_sink_s.h" +#include "blocks/vector_sink_i.h" +#include "blocks/vector_sink_f.h" +#include "blocks/vector_sink_c.h" +#include "blocks/vector_source_b.h" +#include "blocks/vector_source_s.h" +#include "blocks/vector_source_i.h" +#include "blocks/vector_source_f.h" +#include "blocks/vector_source_c.h" #include "blocks/wavfile_sink.h" #include "blocks/wavfile_source.h" #include "blocks/xor_bb.h" @@ -235,6 +261,7 @@ %include "blocks/complex_to_arg.h" %include "blocks/conjugate_cc.h" %include "blocks/control_loop.h" +%include "blocks/copy.h" %include "blocks/deinterleave.h" %include "blocks/delay.h" %include "blocks/file_descriptor_sink.h" @@ -248,11 +275,13 @@ %include "blocks/divide_ss.h" %include "blocks/divide_ii.h" %include "blocks/divide_cc.h" +%include "blocks/endian_swap.h" %include "blocks/float_to_char.h" %include "blocks/float_to_complex.h" %include "blocks/float_to_int.h" %include "blocks/float_to_short.h" %include "blocks/float_to_uchar.h" +%include "blocks/head.h" %include "blocks/int_to_float.h" %include "blocks/integrate_ss.h" %include "blocks/integrate_ii.h" @@ -292,9 +321,12 @@ %include "blocks/mute_ff.h" %include "blocks/mute_cc.h" %include "blocks/nlog10_ff.h" +%include "blocks/nop.h" %include "blocks/not_bb.h" %include "blocks/not_ss.h" %include "blocks/not_ii.h" +%include "blocks/null_sink.h" +%include "blocks/null_source.h" %include "blocks/probe_signal_b.h" %include "blocks/probe_signal_s.h" %include "blocks/probe_signal_i.h" @@ -332,6 +364,7 @@ %include "blocks/sample_and_hold_ff.h" %include "blocks/short_to_char.h" %include "blocks/short_to_float.h" +%include "blocks/skiphead.h" %include "blocks/socket_pdu.h" %include "blocks/stream_mux.h" %include "blocks/stream_to_streams.h" @@ -358,8 +391,24 @@ %include "blocks/unpacked_to_packed_ss.h" %include "blocks/unpacked_to_packed_ii.h" %include "blocks/vco_f.h" +%include "blocks/vector_map.h" %include "blocks/vector_to_stream.h" %include "blocks/vector_to_streams.h" +%include "blocks/vector_insert_b.h" +%include "blocks/vector_insert_s.h" +%include "blocks/vector_insert_i.h" +%include "blocks/vector_insert_f.h" +%include "blocks/vector_insert_c.h" +%include "blocks/vector_sink_b.h" +%include "blocks/vector_sink_s.h" +%include "blocks/vector_sink_i.h" +%include "blocks/vector_sink_f.h" +%include "blocks/vector_sink_c.h" +%include "blocks/vector_source_b.h" +%include "blocks/vector_source_s.h" +%include "blocks/vector_source_i.h" +%include "blocks/vector_source_f.h" +%include "blocks/vector_source_c.h" %include "blocks/wavfile_sink.h" %include "blocks/wavfile_source.h" %include "blocks/xor_bb.h" @@ -401,8 +450,10 @@ GR_SWIG_BLOCK_MAGIC2(blocks, complex_to_mag); GR_SWIG_BLOCK_MAGIC2(blocks, complex_to_mag_squared); GR_SWIG_BLOCK_MAGIC2(blocks, complex_to_arg); GR_SWIG_BLOCK_MAGIC2(blocks, conjugate_cc); +GR_SWIG_BLOCK_MAGIC2(blocks, copy); GR_SWIG_BLOCK_MAGIC2(blocks, deinterleave); GR_SWIG_BLOCK_MAGIC2(blocks, delay); +GR_SWIG_BLOCK_MAGIC2(blocks, endian_swap); GR_SWIG_BLOCK_MAGIC2(blocks, divide_ff); GR_SWIG_BLOCK_MAGIC2(blocks, divide_ss); GR_SWIG_BLOCK_MAGIC2(blocks, divide_ii); @@ -418,6 +469,7 @@ GR_SWIG_BLOCK_MAGIC2(blocks, float_to_complex); GR_SWIG_BLOCK_MAGIC2(blocks, float_to_int); GR_SWIG_BLOCK_MAGIC2(blocks, float_to_short); GR_SWIG_BLOCK_MAGIC2(blocks, float_to_uchar); +GR_SWIG_BLOCK_MAGIC2(blocks, head); GR_SWIG_BLOCK_MAGIC2(blocks, int_to_float); GR_SWIG_BLOCK_MAGIC2(blocks, integrate_ss); GR_SWIG_BLOCK_MAGIC2(blocks, integrate_ii); @@ -457,9 +509,12 @@ GR_SWIG_BLOCK_MAGIC2(blocks, mute_ii); GR_SWIG_BLOCK_MAGIC2(blocks, mute_ff); GR_SWIG_BLOCK_MAGIC2(blocks, mute_cc); GR_SWIG_BLOCK_MAGIC2(blocks, nlog10_ff); +GR_SWIG_BLOCK_MAGIC2(blocks, nop); GR_SWIG_BLOCK_MAGIC2(blocks, not_bb); GR_SWIG_BLOCK_MAGIC2(blocks, not_ss); GR_SWIG_BLOCK_MAGIC2(blocks, not_ii); +GR_SWIG_BLOCK_MAGIC2(blocks, null_sink); +GR_SWIG_BLOCK_MAGIC2(blocks, null_source); GR_SWIG_BLOCK_MAGIC2(blocks, patterned_interleaver); GR_SWIG_BLOCK_MAGIC2(blocks, pack_k_bits_bb); GR_SWIG_BLOCK_MAGIC2(blocks, packed_to_unpacked_bb); @@ -496,6 +551,7 @@ GR_SWIG_BLOCK_MAGIC2(blocks, sample_and_hold_ii); GR_SWIG_BLOCK_MAGIC2(blocks, sample_and_hold_ff); GR_SWIG_BLOCK_MAGIC2(blocks, short_to_char); GR_SWIG_BLOCK_MAGIC2(blocks, short_to_float); +GR_SWIG_BLOCK_MAGIC2(blocks, skiphead); GR_SWIG_BLOCK_MAGIC2(blocks, socket_pdu); GR_SWIG_BLOCK_MAGIC2(blocks, stream_mux); GR_SWIG_BLOCK_MAGIC2(blocks, stream_to_streams); @@ -523,8 +579,24 @@ GR_SWIG_BLOCK_MAGIC2(blocks, unpacked_to_packed_bb); GR_SWIG_BLOCK_MAGIC2(blocks, unpacked_to_packed_ss); GR_SWIG_BLOCK_MAGIC2(blocks, unpacked_to_packed_ii); GR_SWIG_BLOCK_MAGIC2(blocks, vco_f); +GR_SWIG_BLOCK_MAGIC2(blocks, vector_map); GR_SWIG_BLOCK_MAGIC2(blocks, vector_to_stream); GR_SWIG_BLOCK_MAGIC2(blocks, vector_to_streams); +GR_SWIG_BLOCK_MAGIC2(blocks, vector_insert_b); +GR_SWIG_BLOCK_MAGIC2(blocks, vector_insert_s); +GR_SWIG_BLOCK_MAGIC2(blocks, vector_insert_i); +GR_SWIG_BLOCK_MAGIC2(blocks, vector_insert_f); +GR_SWIG_BLOCK_MAGIC2(blocks, vector_insert_c); +GR_SWIG_BLOCK_MAGIC2(blocks, vector_sink_b); +GR_SWIG_BLOCK_MAGIC2(blocks, vector_sink_s); +GR_SWIG_BLOCK_MAGIC2(blocks, vector_sink_i); +GR_SWIG_BLOCK_MAGIC2(blocks, vector_sink_f); +GR_SWIG_BLOCK_MAGIC2(blocks, vector_sink_c); +GR_SWIG_BLOCK_MAGIC2(blocks, vector_source_b); +GR_SWIG_BLOCK_MAGIC2(blocks, vector_source_s); +GR_SWIG_BLOCK_MAGIC2(blocks, vector_source_i); +GR_SWIG_BLOCK_MAGIC2(blocks, vector_source_f); +GR_SWIG_BLOCK_MAGIC2(blocks, vector_source_c); GR_SWIG_BLOCK_MAGIC2(blocks, wavfile_sink); GR_SWIG_BLOCK_MAGIC2(blocks, wavfile_source); GR_SWIG_BLOCK_MAGIC2(blocks, xor_bb); |