diff options
Diffstat (limited to 'gnuradio-core/src')
24 files changed, 964 insertions, 8 deletions
diff --git a/gnuradio-core/src/lib/general/CMakeLists.txt b/gnuradio-core/src/lib/general/CMakeLists.txt index 207d85c4c..ab9b870aa 100644 --- a/gnuradio-core/src/lib/general/CMakeLists.txt +++ b/gnuradio-core/src/lib/general/CMakeLists.txt @@ -228,6 +228,7 @@ set(gr_core_general_triple_threats gr_interleaved_short_to_complex gr_iqcomp_cc gr_keep_one_in_n + gr_keep_m_in_n gr_kludge_copy gr_lfsr_32k_source_s gr_map_bb @@ -281,9 +282,11 @@ set(gr_core_general_triple_threats gr_transcendental gr_uchar_to_float gr_vco_f + gr_vector_map gr_vector_to_stream gr_vector_to_streams gr_unpack_k_bits_bb + gr_pack_k_bits_bb gr_descrambler_bb gr_scrambler_bb gr_probe_density_b diff --git a/gnuradio-core/src/lib/general/general.i b/gnuradio-core/src/lib/general/general.i index cd8c279c9..0696addbd 100644 --- a/gnuradio-core/src/lib/general/general.i +++ b/gnuradio-core/src/lib/general/general.i @@ -37,6 +37,7 @@ #include <gr_stream_to_vector.h> #include <gr_vector_to_stream.h> #include <gr_keep_one_in_n.h> +#include <gr_keep_m_in_n.h> #include <gr_fft_vcc.h> #include <gr_fft_vfc.h> #include <gr_float_to_int.h> @@ -100,6 +101,7 @@ #include <gr_test_types.h> #include <gr_test.h> #include <gr_unpack_k_bits_bb.h> +#include <gr_pack_k_bits_bb.h> #include <gr_diff_phasor_cc.h> #include <gr_diff_encoder_bb.h> #include <gr_diff_decoder_bb.h> @@ -137,6 +139,7 @@ #include <gr_cpm.h> #include <gr_correlate_access_code_tag_bb.h> #include <gr_add_ff.h> +#include <gr_vector_map.h> %} %include "gri_control_loop.i" @@ -154,6 +157,7 @@ %include "gr_stream_to_vector.i" %include "gr_vector_to_stream.i" %include "gr_keep_one_in_n.i" +%include "gr_keep_m_in_n.i" %include "gr_fft_vcc.i" %include "gr_fft_vfc.i" %include "gr_float_to_int.i" @@ -217,6 +221,7 @@ %include "gr_test_types.h" %include "gr_test.i" %include "gr_unpack_k_bits_bb.i" +%include "gr_pack_k_bits_bb.i" %include "gr_diff_phasor_cc.i" %include "gr_diff_encoder_bb.i" %include "gr_diff_decoder_bb.i" @@ -254,3 +259,4 @@ %include "gr_cpm.i" %include "gr_correlate_access_code_tag_bb.i" %include "gr_add_ff.i" +%include "gr_vector_map.i" diff --git a/gnuradio-core/src/lib/general/gr_head.h b/gnuradio-core/src/lib/general/gr_head.h index 17dd737f0..48415892d 100644 --- a/gnuradio-core/src/lib/general/gr_head.h +++ b/gnuradio-core/src/lib/general/gr_head.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2009 Free Software Foundation, Inc. + * Copyright 2004,2009,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -51,6 +51,7 @@ class GR_CORE_API gr_head : public gr_sync_block gr_vector_void_star &output_items); void reset() { d_ncopied_items = 0; } + void set_length(int nitems) { d_nitems = nitems; } }; GR_CORE_API gr_head_sptr diff --git a/gnuradio-core/src/lib/general/gr_head.i b/gnuradio-core/src/lib/general/gr_head.i index 73feaf181..11f3331d4 100644 --- a/gnuradio-core/src/lib/general/gr_head.i +++ b/gnuradio-core/src/lib/general/gr_head.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2009 Free Software Foundation, Inc. + * Copyright 2004,2009,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -28,5 +28,6 @@ class gr_head : public gr_block { gr_head(); public: void reset(); + void set_length(int nitems); }; diff --git a/gnuradio-core/src/lib/general/gr_keep_m_in_n.cc b/gnuradio-core/src/lib/general/gr_keep_m_in_n.cc new file mode 100644 index 000000000..760a01c8c --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_keep_m_in_n.cc @@ -0,0 +1,86 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_keep_m_in_n.h> +#include <gr_io_signature.h> +#include <string.h> +#include <stdio.h> + +gr_keep_m_in_n_sptr +gr_make_keep_m_in_n(size_t item_size, int m, int n, int offset) +{ + return gnuradio::get_initial_sptr(new gr_keep_m_in_n(item_size, m, n, offset)); +} + + +/* +* +* offset = 0, starts with 0th item +* offset = 1, starts with 1st item, etc... +* +* we take m items out of each n +*/ +gr_keep_m_in_n::gr_keep_m_in_n(size_t item_size, int m, int n, int offset) + : gr_sync_block ("keep_m_in_n", + gr_make_io_signature(1, 1, n*item_size), + gr_make_io_signature(1, 1, m*item_size)), + d_n(n), + d_m(m), + d_offset(offset) +{ + // sanity checking + assert(d_m > 0); + assert(d_n > 0); + assert(d_m <= d_n); + assert(d_offset <= (d_n-d_m)); +} + + +void gr_keep_m_in_n::set_offset(int offset) +{ + d_offset = offset; +} + + +int +gr_keep_m_in_n::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + uint8_t* out = (uint8_t*)output_items[0]; + const uint8_t* in = (const uint8_t*)input_items[0]; + + int in_item( input_signature()->sizeof_stream_item(0) ); + int out_item( output_signature()->sizeof_stream_item(0) ); + int single_size = in_item/d_n; + + // iterate over data blocks of size {n, input : m, output} + for(int i = 0; i < noutput_items; i++) { + memcpy(&out[out_item*i], &in[in_item*i + single_size*d_offset], out_item); + } + + return noutput_items; +} diff --git a/gnuradio-core/src/lib/general/gr_keep_m_in_n.h b/gnuradio-core/src/lib/general/gr_keep_m_in_n.h new file mode 100644 index 000000000..4783aaba3 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_keep_m_in_n.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_KEEP_M_IN_N_H +#define INCLUDED_GR_KEEP_M_IN_N_H + +#include <gr_core_api.h> +#include <gr_sync_block.h> + +class gr_keep_m_in_n; +typedef boost::shared_ptr<gr_keep_m_in_n> gr_keep_m_in_n_sptr; + +GR_CORE_API gr_keep_m_in_n_sptr +gr_make_keep_m_in_n (size_t item_size, int m, int n, int offset); + + +/*! + * \brief decimate a stream, keeping one item out of every n. + * \ingroup slicedice_blk + */ +class GR_CORE_API gr_keep_m_in_n : public gr_sync_block +{ + friend GR_CORE_API gr_keep_m_in_n_sptr + gr_make_keep_m_in_n (size_t item_size, int m, int n, int offset); + + int d_n; + int d_m; + int d_count; + int d_offset; + + protected: + gr_keep_m_in_n (size_t item_size, int m, int n, int offset); + + public: + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + void set_offset(int offset); + +}; + +#endif /* INCLUDED_GR_KEEP_M_IN_N_H */ diff --git a/gnuradio-core/src/lib/general/gr_keep_m_in_n.i b/gnuradio-core/src/lib/general/gr_keep_m_in_n.i new file mode 100644 index 000000000..f280c0248 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_keep_m_in_n.i @@ -0,0 +1,35 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +GR_SWIG_BLOCK_MAGIC(gr,keep_m_in_n) + +gr_keep_m_in_n_sptr +gr_make_keep_m_in_n (size_t itemsize, int m, int n, int offset); + +class gr_keep_m_in_n : public gr_sync_block +{ + protected: + gr_keep_m_in_n (size_t itemsize, int m, int n, int offset); + public: + void set_offset(int offset); + +}; diff --git a/gnuradio-core/src/lib/general/gr_pack_k_bits_bb.cc b/gnuradio-core/src/lib/general/gr_pack_k_bits_bb.cc new file mode 100644 index 000000000..4bd7ca4bb --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_pack_k_bits_bb.cc @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_pack_k_bits_bb.h> +#include <gr_io_signature.h> +#include <stdexcept> +#include <iostream> + +gr_pack_k_bits_bb_sptr gr_make_pack_k_bits_bb(unsigned k) +{ + return gnuradio::get_initial_sptr(new gr_pack_k_bits_bb(k)); +} + + +gr_pack_k_bits_bb::gr_pack_k_bits_bb (unsigned k) + : gr_sync_decimator("pack_k_bits_bb", + gr_make_io_signature (1, 1, sizeof(unsigned char)), + gr_make_io_signature (1, 1, sizeof(unsigned char)), + k), + d_k (k) +{ + if (d_k == 0) + throw std::out_of_range("interpolation must be > 0"); +} + +gr_pack_k_bits_bb::~gr_pack_k_bits_bb() +{ +} + +int +gr_pack_k_bits_bb::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const unsigned char *in = (const unsigned char *)input_items[0]; + unsigned char *out = (unsigned char *)output_items[0]; + + for(int i = 0; i < noutput_items; i++) { + out[i] = 0x00; + for(unsigned int j = 0; j < d_k; j++) { + out[i] |= (0x01 & in[i*d_k+j])<<j; + } + } + + return noutput_items; +} diff --git a/gnuradio-core/src/lib/general/gr_pack_k_bits_bb.h b/gnuradio-core/src/lib/general/gr_pack_k_bits_bb.h new file mode 100644 index 000000000..8e1508c78 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_pack_k_bits_bb.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_PACK_K_BITS_BB_H +#define INCLUDED_GR_PACK_K_BITS_BB_H + +#include <gr_core_api.h> +#include <gr_sync_decimator.h> + +class gr_pack_k_bits_bb; +typedef boost::shared_ptr<gr_pack_k_bits_bb> gr_pack_k_bits_bb_sptr; +GR_CORE_API gr_pack_k_bits_bb_sptr gr_make_pack_k_bits_bb (unsigned k); + +class gr_pack_k_bits_bb; + +/*! + * \brief Converts a stream of bytes with 1 bit in the LSB to a byte with k relevent bits. + * \ingroup converter_blk + */ +class GR_CORE_API gr_pack_k_bits_bb : public gr_sync_decimator +{ + private: + friend GR_CORE_API gr_pack_k_bits_bb_sptr gr_make_pack_k_bits_bb (unsigned k); + + gr_pack_k_bits_bb (unsigned k); + + unsigned d_k; // number of relevent bits to pack from k input bytes + + public: + ~gr_pack_k_bits_bb (); + + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif diff --git a/gnuradio-core/src/lib/general/gr_pack_k_bits_bb.i b/gnuradio-core/src/lib/general/gr_pack_k_bits_bb.i new file mode 100644 index 000000000..6ae2095ec --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_pack_k_bits_bb.i @@ -0,0 +1,34 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +GR_SWIG_BLOCK_MAGIC(gr,pack_k_bits_bb) + +gr_pack_k_bits_bb_sptr gr_make_pack_k_bits_bb (int k) throw(std::exception); + +class gr_pack_k_bits_bb : public gr_sync_decimator +{ + private: + gr_pack_k_bits_bb (int k); + + public: + ~gr_pack_k_bits_bb (); +}; diff --git a/gnuradio-core/src/lib/general/gr_vector_map.cc b/gnuradio-core/src/lib/general/gr_vector_map.cc new file mode 100644 index 000000000..2a13efb06 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_vector_map.cc @@ -0,0 +1,117 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_vector_map.h> +#include <gr_io_signature.h> +#include <string.h> + +std::vector<int> +get_in_sizeofs(size_t item_size, std::vector<size_t> in_vlens) +{ + std::vector<int> in_sizeofs; + for(unsigned int i = 0; i < in_vlens.size(); i++) { + in_sizeofs.push_back(in_vlens[i]*item_size); + } + return in_sizeofs; +} + +std::vector<int> +get_out_sizeofs(size_t item_size, + std::vector< std::vector< std::vector<size_t> > > mapping) +{ + std::vector<int> out_sizeofs; + for(unsigned int i = 0; i < mapping.size(); i++) { + out_sizeofs.push_back(mapping[i].size()*item_size); + } + return out_sizeofs; +} + +gr_vector_map_sptr +gr_make_vector_map (size_t item_size, std::vector<size_t> in_vlens, + std::vector< std::vector< std::vector<size_t> > > mapping) +{ + return gnuradio::get_initial_sptr(new gr_vector_map(item_size, + in_vlens, + mapping)); +} + +gr_vector_map::gr_vector_map(size_t item_size, std::vector<size_t> in_vlens, + std::vector< std::vector< std::vector<size_t> > > mapping) + : gr_sync_block("vector_map", + gr_make_io_signaturev(in_vlens.size(), in_vlens.size(), + get_in_sizeofs(item_size, in_vlens)), + gr_make_io_signaturev(mapping.size(), mapping.size(), + get_out_sizeofs(item_size, mapping))), + d_item_size(item_size), d_in_vlens(in_vlens) +{ + set_mapping(mapping); +} + +void +gr_vector_map::set_mapping(std::vector< std::vector< std::vector<size_t> > > mapping) { + // Make sure the contents of the mapping vectors are possible. + for(unsigned int i=0; i<mapping.size(); i++) { + for(unsigned int j=0; j<mapping[i].size(); j++) { + if(mapping[i][j].size() != 2) { + throw std::runtime_error("Mapping must be of the form (out_mapping_stream1, out_mapping_stream2, ...), where out_mapping_stream1 is of the form (mapping_element1, mapping_element2, ...), where mapping_element1 is of the form (input_stream, input_element). This error is raised because a mapping_element vector does not contain exactly 2 items."); + } + unsigned int s = mapping[i][j][0]; + unsigned int index = mapping[i][j][1]; + if(s >= d_in_vlens.size()) { + throw std::runtime_error("Stream numbers in mapping must be less than the number of input streams."); + } + if((index < 0) || (index >= d_in_vlens[s])) { + throw std::runtime_error ("Indices in mapping must be greater than 0 and less than the input vector lengths."); + } + } + } + gruel::scoped_lock guard(d_mutex); + d_mapping = mapping; +} + +int +gr_vector_map::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const char **inv = (const char **) &input_items[0]; + char **outv = (char **) &output_items[0]; + + for(unsigned int n = 0; n < (unsigned int)(noutput_items); n++) { + for(unsigned int i = 0; i < d_mapping.size(); i++) { + unsigned int out_vlen = d_mapping[i].size(); + for(unsigned int j = 0; j < out_vlen; j++) { + unsigned int s = d_mapping[i][j][0]; + unsigned int k = d_mapping[i][j][1]; + memcpy(outv[i] + out_vlen*d_item_size*n + + d_item_size*j, inv[s] + d_in_vlens[s]*d_item_size*n + + k*d_item_size, d_item_size); + } + } + } + + return noutput_items; +} diff --git a/gnuradio-core/src/lib/general/gr_vector_map.h b/gnuradio-core/src/lib/general/gr_vector_map.h new file mode 100644 index 000000000..f5492b1e3 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_vector_map.h @@ -0,0 +1,83 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_VECTOR_MAP_H +#define INCLUDED_GR_VECTOR_MAP_H + +#include <vector> +#include <gr_core_api.h> +#include <gr_sync_interpolator.h> +#include <gruel/thread.h> + +class gr_vector_map; +typedef boost::shared_ptr<gr_vector_map> gr_vector_map_sptr; + +GR_CORE_API gr_vector_map_sptr +gr_make_vector_map (size_t item_size, std::vector<size_t> in_vlens, + std::vector< std::vector< std::vector<size_t> > > mapping); + +/*! + * \brief Maps elements from a set of input vectors to a set of output vectors. + * + * If in[i] is the input vector in the i'th stream then the output + * vector in the j'th stream is: + * + * out[j][k] = in[mapping[j][k][0]][mapping[j][k][1]] + * + * That is mapping is of the form (out_stream1_mapping, + * out_stream2_mapping, ...) and out_stream1_mapping is of the form + * (element1_mapping, element2_mapping, ...) and element1_mapping is + * of the form (in_stream, in_element). + * + * \param item_size (integer) size of vector elements + * + * \param in_vlens (vector of integers) number of elements in each + * input vector + * + * \param mapping (vector of vectors of vectors of integers) how to + * map elements from input to output vectors + * + * \ingroup slicedice_blk + */ +class GR_CORE_API gr_vector_map : public gr_sync_block +{ + friend GR_CORE_API gr_vector_map_sptr + gr_make_vector_map(size_t item_size, std::vector<size_t> in_vlens, + std::vector< std::vector< std::vector<size_t> > > mapping); + size_t d_item_size; + std::vector<size_t> d_in_vlens; + std::vector< std::vector< std::vector<size_t> > > d_mapping; + gruel::mutex d_mutex; // mutex to protect set/work access + + protected: + gr_vector_map(size_t item_size, std::vector<size_t> in_vlens, + std::vector< std::vector< std::vector<size_t> > > mapping); + + public: + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + void set_mapping(std::vector< std::vector< std::vector<size_t> > > mapping); +}; + +#endif /* INCLUDED_GR_VECTOR_MAP_H */ diff --git a/gnuradio-core/src/lib/general/gr_vector_map.i b/gnuradio-core/src/lib/general/gr_vector_map.i new file mode 100644 index 000000000..e9fa3f27e --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_vector_map.i @@ -0,0 +1,28 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +GR_SWIG_BLOCK_MAGIC(gr, vector_map); + +%template() std::vector<size_t>; +%template() std::vector< std::vector< std::vector<size_t> > >; + +%include "gr_vector_map.h" diff --git a/gnuradio-core/src/lib/gengen/CMakeLists.txt b/gnuradio-core/src/lib/gengen/CMakeLists.txt index d13776990..22ac1bc58 100644 --- a/gnuradio-core/src/lib/gengen/CMakeLists.txt +++ b/gnuradio-core/src/lib/gengen/CMakeLists.txt @@ -82,6 +82,7 @@ endmacro(expand_h_cc_i) # Invoke macro to generate various sources ######################################################################## expand_h_cc_i(gr_vector_source_X b s i f c) +expand_h_cc_i(gr_vector_insert_X b) expand_h_cc_i(gr_vector_sink_X b s i f c) expand_h_cc_i(gr_noise_source_X s i f c) expand_h_cc_i(gr_sig_source_X s i f c) diff --git a/gnuradio-core/src/lib/gengen/gr_vector_insert_X.cc.t b/gnuradio-core/src/lib/gengen/gr_vector_insert_X.cc.t new file mode 100644 index 000000000..37963cdfe --- /dev/null +++ b/gnuradio-core/src/lib/gengen/gr_vector_insert_X.cc.t @@ -0,0 +1,100 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <@NAME@.h> +#include <algorithm> +#include <gr_io_signature.h> +#include <stdexcept> + +#include <stdio.h> + +@NAME@::@NAME@(const std::vector<@TYPE@> &data, int periodicity, int offset) + : gr_block("@BASE_NAME@", + gr_make_io_signature (1, 1, sizeof(@TYPE@)), + gr_make_io_signature (1, 1, sizeof(@TYPE@))), + d_data(data), + d_offset(offset), + d_periodicity(periodicity) +{ + //printf("INITIAL: periodicity = %d, offset = %d\n", periodicity, offset); + // some sanity checks + assert(offset < periodicity); + assert(offset >= 0); + assert(periodicity > data.size()); +} + +int +@NAME@::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + @TYPE@ *out = (@TYPE@ *)output_items[0]; + const @TYPE@ *in = (const @TYPE@ *)input_items[0]; + + int ii(0), oo(0); + + while((oo < noutput_items) && (ii < ninput_items[0])) { + + //printf("oo = %d, ii = %d, d_offset = %d, noutput_items = %d, ninput_items[0] = %d", oo, ii, d_offset, noutput_items, ninput_items[0]); + //printf(", d_periodicity = %d\n", d_periodicity); + + if(d_offset >= ((int)d_data.size())) { // if we are in the copy region + int max_copy = std::min( std::min( noutput_items - oo, ninput_items[0] - ii ), d_periodicity - d_offset ); + //printf("copy %d from input\n", max_copy); + memcpy( &out[oo], &in[ii], sizeof(@TYPE@)*max_copy ); + //printf(" * memcpy returned.\n"); + ii += max_copy; + oo += max_copy; + d_offset = (d_offset + max_copy)%d_periodicity; + + } + else { // if we are in the insertion region + int max_copy = std::min( noutput_items - oo, ((int)d_data.size()) - d_offset ); + //printf("copy %d from d_data[%d] to out[%d]\n", max_copy, d_offset, oo); + memcpy( &out[oo], &d_data[d_offset], sizeof(@TYPE@)*max_copy ); + //printf(" * memcpy returned.\n"); + oo += max_copy; + d_offset = (d_offset + max_copy)%d_periodicity; + //printf(" ## (inelse) oo = %d, d_offset = %d\n", oo, d_offset); + } + + //printf(" # exit else, on to next loop.\n"); + } + //printf(" # got out of loop\n"); + + //printf("consume = %d, produce = %d\n", ii, oo); + consume_each(ii); + return oo; +} + +@NAME@_sptr +gr_make_@BASE_NAME@ (const std::vector<@TYPE@> &data, int periodicity, int offset) +{ + return gnuradio::get_initial_sptr(new @NAME@ (data, periodicity, offset)); +} + diff --git a/gnuradio-core/src/lib/gengen/gr_vector_insert_X.h.t b/gnuradio-core/src/lib/gengen/gr_vector_insert_X.h.t new file mode 100644 index 000000000..26f851700 --- /dev/null +++ b/gnuradio-core/src/lib/gengen/gr_vector_insert_X.h.t @@ -0,0 +1,61 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <gr_core_api.h> +#include <gr_block.h> + +class GR_CORE_API @NAME@; +typedef boost::shared_ptr<@NAME@> @NAME@_sptr; + +/*! + * \brief source of @TYPE@'s that gets its data from a vector + * \ingroup source_blk + */ + +class @NAME@ : public gr_block { + friend GR_CORE_API @NAME@_sptr + gr_make_@BASE_NAME@(const std::vector<@TYPE@> &data, int periodicity, int offset); + + std::vector<@TYPE@> d_data; + int d_offset; + int d_periodicity; + + @NAME@(const std::vector<@TYPE@> &data, int periodicity, int offset); + + public: + void rewind() {d_offset=0;} + virtual int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + void set_data(const std::vector<@TYPE@> &data){ d_data = data; rewind(); } +}; + +GR_CORE_API @NAME@_sptr +gr_make_@BASE_NAME@(const std::vector<@TYPE@> &data, int periodicity, int offset=0); + +#endif diff --git a/gnuradio-core/src/lib/gengen/gr_vector_insert_X.i.t b/gnuradio-core/src/lib/gengen/gr_vector_insert_X.i.t new file mode 100644 index 000000000..f3341eec4 --- /dev/null +++ b/gnuradio-core/src/lib/gengen/gr_vector_insert_X.i.t @@ -0,0 +1,37 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@); + +@NAME@_sptr +gr_make_@BASE_NAME@ (const std::vector<@TYPE@> &data, int periodicity, int offset = 0) + throw(std::invalid_argument); + +class @NAME@ : public gr_block { + public: + void rewind(); + void set_data(const std::vector<@TYPE@> &data); + private: + @NAME@ (const std::vector<@TYPE@> &data, int periodicity, int offset = 0); +}; diff --git a/gnuradio-core/src/lib/gengen/gr_vector_source_X.h.t b/gnuradio-core/src/lib/gengen/gr_vector_source_X.h.t index fe0a77f81..fe02c1346 100644 --- a/gnuradio-core/src/lib/gengen/gr_vector_source_X.h.t +++ b/gnuradio-core/src/lib/gengen/gr_vector_source_X.h.t @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2008 Free Software Foundation, Inc. + * Copyright 2004,2008,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -52,6 +52,7 @@ class @NAME@ : public gr_sync_block { virtual int work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); + void set_data(const std::vector<@TYPE@> &data){ d_data = data; rewind(); } }; GR_CORE_API @NAME@_sptr diff --git a/gnuradio-core/src/lib/gengen/gr_vector_source_X.i.t b/gnuradio-core/src/lib/gengen/gr_vector_source_X.i.t index 6c20539ac..4986c68a3 100644 --- a/gnuradio-core/src/lib/gengen/gr_vector_source_X.i.t +++ b/gnuradio-core/src/lib/gengen/gr_vector_source_X.i.t @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2008 Free Software Foundation, Inc. + * Copyright 2004,2008,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -30,7 +30,8 @@ gr_make_@BASE_NAME@ (const std::vector<@TYPE@> &data, bool repeat = false, int v class @NAME@ : public gr_sync_block { public: - void rewind() {d_offset=0;} + void rewind(); + void set_data(const std::vector<@TYPE@> &data); private: @NAME@ (const std::vector<@TYPE@> &data, int vlen); }; diff --git a/gnuradio-core/src/lib/swig/gnuradio.i b/gnuradio-core/src/lib/swig/gnuradio.i index 239223851..3a421ad5d 100644 --- a/gnuradio-core/src/lib/swig/gnuradio.i +++ b/gnuradio-core/src/lib/swig/gnuradio.i @@ -20,6 +20,9 @@ * Boston, MA 02110-1301, USA. */ +// Disable warning about base class types +#pragma SWIG nowarn=401 + //////////////////////////////////////////////////////////////////////// // gnuradio.i // SWIG interface definition diff --git a/gnuradio-core/src/lib/swig/gr_swig_block_magic.i b/gnuradio-core/src/lib/swig/gr_swig_block_magic.i index cdc9fbe49..4016ae772 100644 --- a/gnuradio-core/src/lib/swig/gr_swig_block_magic.i +++ b/gnuradio-core/src/lib/swig/gr_swig_block_magic.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2010 Free Software Foundation, Inc. + * Copyright 2004,2010,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -40,3 +40,11 @@ FULL_NAME ## _sptr.__repr__ = lambda self: "<gr_block %s (%d)>" % (self.name(), %} %enddef #endif + +%define GR_SWIG_BLOCK_MAGIC2(PKG, BASE_NAME) +%template(BASE_NAME ## _sptr) boost::shared_ptr<gr:: ## PKG ## :: ## BASE_NAME>; +%pythoncode %{ +BASE_NAME ## _sptr.__repr__ = lambda self: "<gr_block %s (%d)>" % (self.name(), self.unique_id()) +BASE_NAME = BASE_NAME.make; +%} +%enddef diff --git a/gnuradio-core/src/python/build_utils.py b/gnuradio-core/src/python/build_utils.py index 0660941d5..ce0757912 100644 --- a/gnuradio-core/src/python/build_utils.py +++ b/gnuradio-core/src/python/build_utils.py @@ -176,11 +176,11 @@ def is_complex (code3): return '0' -def standard_dict (name, code3): +def standard_dict (name, code3, package='gr'): d = {} d['NAME'] = name d['GUARD_NAME'] = 'INCLUDED_%s_H' % name.upper () - d['BASE_NAME'] = re.sub ('^gr_', '', name) + d['BASE_NAME'] = re.sub ('^' + package + '_', '', name) d['SPTR_NAME'] = '%s_sptr' % name d['WARNING'] = 'WARNING: this file is machine generated. Edits will be over written' d['COPYRIGHT'] = copyright diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_vector_insert.py b/gnuradio-core/src/python/gnuradio/gr/qa_vector_insert.py new file mode 100755 index 000000000..acc06dfde --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/gr/qa_vector_insert.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import math + +class test_vector_insert(gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_001(self): + src_data = [float(x) for x in range(16)] + expected_result = tuple(src_data) + + period = 9177; + offset = 0; + + src = gr.null_source(1) + head = gr.head(1, 10000000); + ins = gr.vector_insert_b([1], period, offset); + dst = gr.vector_sink_b() + + self.tb.connect(src, head, ins, dst) + self.tb.run() + result_data = dst.data() + + for i in range(10000): + if(i%period == offset): + self.assertEqual(1, result_data[i]) + else: + self.assertEqual(0, result_data[i]) + +if __name__ == '__main__': + gr_unittest.run(test_vector_insert, "test_vector_insert.xml") + diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_vector_map.py b/gnuradio-core/src/python/gnuradio/gr/qa_vector_map.py new file mode 100644 index 000000000..12f4be589 --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/gr/qa_vector_map.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import math + +class test_vector_map(gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block() + + def tearDown (self): + self.tb = None + + def test_reversing(self): + # Chunk data in blocks of N and reverse the block contents. + N = 5 + src_data = range(0, 20) + expected_result = [] + for i in range(N-1, len(src_data), N): + for j in range(0, N): + expected_result.append(1.0*(i-j)) + mapping = [list(reversed([(0, i) for i in range(0, N)]))] + src = gr.vector_source_f(src_data, False, N) + vmap = gr.vector_map(gr.sizeof_float, (N, ), mapping) + dst = gr.vector_sink_f(N) + self.tb.connect(src, vmap, dst) + self.tb.run() + result_data = list(dst.data()) + self.assertEqual(expected_result, result_data) + + def test_vector_to_streams(self): + # Split an input vector into N streams. + N = 5 + M = 20 + src_data = range(0, M) + expected_results = [] + for n in range(0, N): + expected_results.append(range(n, M, N)) + mapping = [[(0, n)] for n in range(0, N)] + src = gr.vector_source_f(src_data, False, N) + vmap = gr.vector_map(gr.sizeof_float, (N, ), mapping) + dsts = [gr.vector_sink_f(1) for n in range(0, N)] + self.tb.connect(src, vmap) + for n in range(0, N): + self.tb.connect((vmap, n), dsts[n]) + self.tb.run() + for n in range(0, N): + result_data = list(dsts[n].data()) + self.assertEqual(expected_results[n], result_data) + + def test_interleaving(self): + # Takes 3 streams (a, b and c) + # Outputs 2 streams. + # First (d) is interleaving of a and b. + # Second (e) is interleaving of a and b and c. c is taken in + # chunks of 2 which are reversed. + A = (1, 2, 3, 4, 5) + B = (11, 12, 13, 14, 15) + C = (99, 98, 97, 96, 95, 94, 93, 92, 91, 90) + expected_D = (1, 11, 2, 12, 3, 13, 4, 14, 5, 15) + expected_E = (1, 11, 98, 99, 2, 12, 96, 97, 3, 13, 94, 95, + 4, 14, 92, 93, 5, 15, 90, 91) + mapping = [[(0, 0), (1, 0)], # mapping to produce D + [(0, 0), (1, 0), (2, 1), (2, 0)], # mapping to produce E + ] + srcA = gr.vector_source_f(A, False, 1) + srcB = gr.vector_source_f(B, False, 1) + srcC = gr.vector_source_f(C, False, 2) + vmap = gr.vector_map(gr.sizeof_int, (1, 1, 2), mapping) + dstD = gr.vector_sink_f(2) + dstE = gr.vector_sink_f(4) + self.tb.connect(srcA, (vmap, 0)) + self.tb.connect(srcB, (vmap, 1)) + self.tb.connect(srcC, (vmap, 2)) + self.tb.connect((vmap, 0), dstD) + self.tb.connect((vmap, 1), dstE) + self.tb.run() + self.assertEqual(expected_D, dstD.data()) + self.assertEqual(expected_E, dstE.data()) + + + +if __name__ == '__main__': + gr_unittest.run(test_vector_map, "test_vector_map.xml") + |