summaryrefslogtreecommitdiff
path: root/gr-digital/lib/burst_shaper_XX_impl.cc.t
diff options
context:
space:
mode:
Diffstat (limited to 'gr-digital/lib/burst_shaper_XX_impl.cc.t')
-rw-r--r--gr-digital/lib/burst_shaper_XX_impl.cc.t353
1 files changed, 353 insertions, 0 deletions
diff --git a/gr-digital/lib/burst_shaper_XX_impl.cc.t b/gr-digital/lib/burst_shaper_XX_impl.cc.t
new file mode 100644
index 0000000000..85add49115
--- /dev/null
+++ b/gr-digital/lib/burst_shaper_XX_impl.cc.t
@@ -0,0 +1,353 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2015 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along 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 <boost/format.hpp>
+#include <gnuradio/io_signature.h>
+#include <volk/volk.h>
+#include "@IMPL_NAME@.h"
+
+#ifndef VOLK_MULT_gr_complex
+#define VOLK_MULT_gr_complex volk_32fc_x2_multiply_32fc
+#endif
+#ifndef VOLK_MULT_float
+#define VOLK_MULT_float volk_32f_x2_multiply_32f
+#endif
+
+namespace gr {
+ namespace digital {
+
+ @BASE_NAME@::sptr
+ @BASE_NAME@::make(const std::vector<@I_TYPE@> &taps,
+ int pre_padding, int post_padding,
+ bool insert_phasing,
+ const std::string &length_tag_name)
+ {
+ return gnuradio::get_initial_sptr
+ (new @IMPL_NAME@(taps, pre_padding, post_padding,
+ insert_phasing, length_tag_name));
+ }
+
+ @IMPL_NAME@::@IMPL_NAME@(const std::vector<@I_TYPE@> &taps,
+ int pre_padding, int post_padding,
+ bool insert_phasing,
+ const std::string &length_tag_name)
+ : gr::block("@BASE_NAME@",
+ gr::io_signature::make(1, 1, sizeof(@I_TYPE@)),
+ gr::io_signature::make(1, 1, sizeof(@O_TYPE@))),
+ d_up_ramp(taps.begin(), taps.begin() + taps.size()/2 + taps.size()%2),
+ d_down_ramp(taps.begin() + taps.size()/2, taps.end()),
+ d_nprepad(pre_padding),
+ d_npostpad(post_padding),
+ d_insert_phasing(insert_phasing),
+ d_length_tag_key(pmt::string_to_symbol(length_tag_name)),
+ d_ncopy(0),
+ d_limit(0),
+ d_index(0),
+ d_length_tag_offset(0),
+ d_finished(false),
+ d_state(STATE_WAIT)
+ {
+ assert(d_up_ramp.size() == d_down_ramp.size());
+
+ d_up_phasing.resize(d_up_ramp.size());
+ d_down_phasing.resize(d_down_ramp.size());
+
+ @I_TYPE@ symbol;
+ for(unsigned int i = 0; i < d_up_ramp.size(); i++) {
+ symbol = (i%2 == 0) ? @I_TYPE@(1.0f) : @I_TYPE@(-1.0f);
+ d_up_phasing[i] = symbol * d_up_ramp[i];
+ d_down_phasing[i] = symbol * d_down_ramp[i];
+ }
+
+ //set_relative_rate(1.0);
+ set_tag_propagation_policy(TPP_DONT);
+ }
+
+ @IMPL_NAME@::~@IMPL_NAME@()
+ {
+ }
+
+ void
+ @IMPL_NAME@::forecast(int noutput_items,
+ gr_vector_int &ninput_items_required)
+ {
+ ninput_items_required[0] = noutput_items;
+ }
+
+ int
+ @IMPL_NAME@::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const @I_TYPE@ *in = reinterpret_cast<const @I_TYPE@ *>(input_items[0]);
+ @O_TYPE@ *out = reinterpret_cast<@O_TYPE@ *>(output_items[0]);
+
+ int nwritten = 0;
+ int nread = 0;
+ int nspace = 0;
+ int nskip = 0;
+ int curr_tag_index = 0;
+
+ std::vector<tag_t> length_tags;
+ get_tags_in_window(length_tags, 0, 0, ninput_items[0], d_length_tag_key);
+ std::sort(length_tags.rbegin(), length_tags.rend(), tag_t::offset_compare);
+
+ while((nwritten < noutput_items) && (nread < ninput_items[0])) {
+ if(d_finished) {
+ d_finished = false;
+ break;
+ }
+ nspace = noutput_items - nwritten;
+ switch(d_state) {
+ case(STATE_WAIT):
+ if(!length_tags.empty()) {
+ d_length_tag_offset = length_tags.back().offset;
+ curr_tag_index = (int)(d_length_tag_offset - nitems_read(0));
+ d_ncopy = pmt::to_long(length_tags.back().value);
+ length_tags.pop_back();
+ nskip = curr_tag_index - nread;
+ add_length_tag(nwritten);
+ propagate_tags(curr_tag_index, nwritten, 1, false);
+ enter_prepad();
+ }
+ else {
+ nskip = ninput_items[0] - nread;
+ }
+ if(nskip > 0) {
+ GR_LOG_WARN(d_logger,
+ boost::format("Dropping %1% samples") %
+ nskip);
+ nread += nskip;
+ in += nskip;
+ }
+ break;
+
+ case(STATE_PREPAD):
+ write_padding(out, nwritten, nspace);
+ if(d_index == d_limit)
+ enter_rampup();
+ break;
+
+ case(STATE_RAMPUP):
+ apply_ramp(out, in, nwritten, nread, nspace);
+ if(d_index == d_limit)
+ enter_copy();
+ break;
+
+ case(STATE_COPY):
+ copy_items(out, in, nwritten, nread, nspace);
+ if(d_index == d_limit)
+ enter_rampdown();
+ break;
+
+ case(STATE_RAMPDOWN):
+ apply_ramp(out, in, nwritten, nread, nspace);
+ if(d_index == d_limit)
+ enter_postpad();
+ break;
+
+ case(STATE_POSTPAD):
+ write_padding(out, nwritten, nspace);
+ if(d_index == d_limit)
+ enter_wait();
+ break;
+
+ default:
+ throw std::runtime_error("@BASE_NAME@: invalid state");
+ }
+ }
+
+ consume_each(nread);
+
+ return nwritten;
+ }
+
+ int
+ @IMPL_NAME@::prefix_length() const
+ {
+ return (d_insert_phasing) ?
+ d_nprepad + d_up_ramp.size() : d_nprepad;
+ }
+
+ int
+ @IMPL_NAME@::suffix_length() const
+ {
+ return (d_insert_phasing) ?
+ d_npostpad + d_down_ramp.size() : d_npostpad;
+ }
+
+ void
+ @IMPL_NAME@::write_padding(@O_TYPE@ *&dst, int &nwritten, int nspace)
+ {
+ int nprocess = std::min(d_limit - d_index, nspace);
+ std::memset(dst, 0x00, nprocess * sizeof(@O_TYPE@));
+ dst += nprocess;
+ nwritten += nprocess;
+ d_index += nprocess;
+ }
+
+ void
+ @IMPL_NAME@::copy_items(@O_TYPE@ *&dst, const @I_TYPE@ *&src, int &nwritten,
+ int &nread, int nspace)
+ {
+ int nprocess = std::min(d_limit - d_index, nspace);
+ propagate_tags(nread, nwritten, nprocess);
+ std::memcpy(dst, src, nprocess * sizeof(@O_TYPE@));
+ dst += nprocess;
+ nwritten += nprocess;
+ src += nprocess;
+ nread += nprocess;
+ d_index += nprocess;
+ }
+
+ void
+ @IMPL_NAME@::apply_ramp(@O_TYPE@ *&dst, const @I_TYPE@ *&src, int &nwritten,
+ int &nread, int nspace)
+ {
+ int nprocess = std::min(d_limit - d_index, nspace);
+ @O_TYPE@ *phasing;
+ const @O_TYPE@ *ramp;
+
+ if(d_state == STATE_RAMPUP) {
+ phasing = &d_up_phasing[d_index];
+ ramp = &d_up_ramp[d_index];
+ }
+ else {
+ phasing = &d_down_phasing[d_index];
+ ramp = &d_down_ramp[d_index];
+ }
+
+ if(d_insert_phasing)
+ std::memcpy(dst, phasing, nprocess * sizeof(@O_TYPE@));
+ else {
+ propagate_tags(nread, nwritten, nprocess);
+ VOLK_MULT_@O_TYPE@(dst, src, ramp, nprocess);
+ src += nprocess;
+ nread += nprocess;
+ }
+
+ dst += nprocess;
+ nwritten += nprocess;
+ d_index += nprocess;
+ }
+
+ void
+ @IMPL_NAME@::add_length_tag(int offset)
+ {
+ add_item_tag(0, nitems_written(0) + offset, d_length_tag_key,
+ pmt::from_long(d_ncopy + prefix_length() +
+ suffix_length()),
+ pmt::string_to_symbol(name()));
+ }
+
+ void
+ @IMPL_NAME@::propagate_tags(int in_offset, int out_offset, int count, bool skip)
+ {
+ uint64_t abs_start = nitems_read(0) + in_offset;
+ uint64_t abs_end = abs_start + count;
+ uint64_t abs_offset = nitems_written(0) + out_offset;
+ tag_t temp_tag;
+
+ std::vector<tag_t> tags;
+ std::vector<tag_t>::iterator it;
+
+ get_tags_in_range(tags, 0, abs_start, abs_end);
+
+ for(it = tags.begin(); it != tags.end(); it++) {
+ if(!pmt::equal(it->key, d_length_tag_key)) {
+ if(skip && (it->offset == d_length_tag_offset))
+ continue;
+ temp_tag = *it;
+ temp_tag.offset = abs_offset + it->offset - abs_start;
+ add_item_tag(0, temp_tag);
+ }
+ }
+ }
+
+ void
+ @IMPL_NAME@::enter_wait()
+ {
+ d_finished = true;
+ d_index = 0;
+ d_state = STATE_WAIT;
+ }
+
+ void
+ @IMPL_NAME@::enter_prepad()
+ {
+ d_limit = d_nprepad;
+ d_index = 0;
+ d_state = STATE_PREPAD;
+ }
+
+ void
+ @IMPL_NAME@::enter_rampup()
+ {
+ if(d_insert_phasing)
+ d_limit = d_up_ramp.size();
+ else
+ d_limit = std::min((size_t)(d_ncopy/2), d_up_ramp.size());
+ d_index = 0;
+ d_state = STATE_RAMPUP;
+ }
+
+ void
+ @IMPL_NAME@::enter_copy()
+ {
+ if(d_insert_phasing)
+ d_limit = d_ncopy;
+ else
+ d_limit = d_ncopy - std::min((size_t)((d_ncopy/2)*2),
+ d_up_ramp.size() +
+ d_down_ramp.size());
+ d_index = 0;
+ d_state = STATE_COPY;
+ }
+
+ void
+ @IMPL_NAME@::enter_rampdown()
+ {
+ if(d_insert_phasing)
+ d_limit = d_down_ramp.size();
+ else
+ d_limit = std::min((size_t)(d_ncopy/2), d_down_ramp.size());
+ d_index = 0;
+ d_state = STATE_RAMPDOWN;
+ }
+
+ void
+ @IMPL_NAME@::enter_postpad()
+ {
+ d_limit = d_npostpad;
+ d_index = 0;
+ d_state = STATE_POSTPAD;
+ }
+
+ } /* namespace digital */
+} /* namespace gr */