diff options
Diffstat (limited to 'gr-digital/lib/chunks_to_symbols_impl.cc')
-rw-r--r-- | gr-digital/lib/chunks_to_symbols_impl.cc | 70 |
1 files changed, 43 insertions, 27 deletions
diff --git a/gr-digital/lib/chunks_to_symbols_impl.cc b/gr-digital/lib/chunks_to_symbols_impl.cc index 76bcac8823..42a8217fba 100644 --- a/gr-digital/lib/chunks_to_symbols_impl.cc +++ b/gr-digital/lib/chunks_to_symbols_impl.cc @@ -14,7 +14,7 @@ #include "chunks_to_symbols_impl.h" #include <gnuradio/io_signature.h> -#include <gnuradio/tag_checker.h> +#include <pmt/pmt.h> #include <cassert> namespace gr { @@ -22,14 +22,15 @@ namespace digital { void set_vector_from_pmt(std::vector<gr_complex>& symbol_table, - pmt::pmt_t& symbol_table_pmt) + const pmt::pmt_t& symbol_table_pmt) { size_t length; const gr_complex* elements = pmt::c32vector_elements(symbol_table_pmt, length); symbol_table.assign(elements, elements + length); } -void set_vector_from_pmt(std::vector<float>& symbol_table, pmt::pmt_t& symbol_table_pmt) +void set_vector_from_pmt(std::vector<float>& symbol_table, + const pmt::pmt_t& symbol_table_pmt) { size_t length; const float* elements = pmt::f32vector_elements(symbol_table_pmt, length); @@ -38,7 +39,8 @@ void set_vector_from_pmt(std::vector<float>& symbol_table, pmt::pmt_t& symbol_ta template <class IN_T, class OUT_T> typename chunks_to_symbols<IN_T, OUT_T>::sptr -chunks_to_symbols<IN_T, OUT_T>::make(const std::vector<OUT_T>& symbol_table, const int D) +chunks_to_symbols<IN_T, OUT_T>::make(const std::vector<OUT_T>& symbol_table, + const unsigned int D) { return gnuradio::make_block_sptr<chunks_to_symbols_impl<IN_T, OUT_T>>(symbol_table, D); @@ -46,17 +48,19 @@ chunks_to_symbols<IN_T, OUT_T>::make(const std::vector<OUT_T>& symbol_table, con template <class IN_T, class OUT_T> chunks_to_symbols_impl<IN_T, OUT_T>::chunks_to_symbols_impl( - const std::vector<OUT_T>& symbol_table, const int D) + const std::vector<OUT_T>& symbol_table, const unsigned int D) : sync_interpolator("chunks_to_symbols", io_signature::make(1, -1, sizeof(IN_T)), io_signature::make(1, -1, sizeof(OUT_T)), D), d_D(D), - d_symbol_table(symbol_table) + d_symbol_table(symbol_table), + symbol_table_key(pmt::mp("set_symbol_table")) { - this->message_port_register_in(pmt::mp("set_symbol_table")); - this->set_msg_handler(pmt::mp("set_symbol_table"), - [this](pmt::pmt_t msg) { this->handle_set_symbol_table(msg); }); + this->message_port_register_in(symbol_table_key); + this->set_msg_handler(symbol_table_key, [this](const pmt::pmt_t& msg) { + this->handle_set_symbol_table(msg); + }); } template <class IN_T, class OUT_T> @@ -66,7 +70,7 @@ chunks_to_symbols_impl<IN_T, OUT_T>::~chunks_to_symbols_impl() template <class IN_T, class OUT_T> void chunks_to_symbols_impl<IN_T, OUT_T>::handle_set_symbol_table( - pmt::pmt_t symbol_table_pmt) + const pmt::pmt_t& symbol_table_pmt) { set_vector_from_pmt(d_symbol_table, symbol_table_pmt); } @@ -86,31 +90,43 @@ int chunks_to_symbols_impl<IN_T, OUT_T>::work(int noutput_items, gr_vector_void_star& output_items) { gr::thread::scoped_lock lock(this->d_setlock); - assert(noutput_items % d_D == 0); - assert(input_items.size() == output_items.size()); - int nstreams = input_items.size(); + auto nstreams = input_items.size(); + for (unsigned int m = 0; m < nstreams; m++) { + const auto* in = reinterpret_cast<const IN_T*>(input_items[m]); + // NB: The compiler can't know whether all specializations of `chunks_to_symbol` + // are subclasses of gr::block. Hence the "this->" hoop we have to jump through to + // access members of parent classes. + size_t in_count = this->nitems_read(m); - for (int m = 0; m < nstreams; m++) { - const IN_T* in = (IN_T*)input_items[m]; - OUT_T* out = (OUT_T*)output_items[m]; + auto out = reinterpret_cast<OUT_T*>(output_items[m]); std::vector<tag_t> tags; this->get_tags_in_range( tags, m, this->nitems_read(m), this->nitems_read(m) + noutput_items / d_D); - tag_checker tchecker(tags); - // per stream processing - for (int i = 0; i < noutput_items / d_D; i++) { + // per tag: all the samples leading up to this tag can be handled straightforward + // with the current settings + for (const auto& tag : tags) { + for (; in_count < tag.offset; ++in_count) { + auto key = static_cast<unsigned int>(*in) * d_D; + for (unsigned int idx = 0; idx < d_D; ++idx) { + *out = d_symbol_table[key + idx]; + ++out; + } + ++in; + } + if (tag.key == symbol_table_key) { + handle_set_symbol_table(tag.value); + } + } - std::vector<tag_t> tags_now; - tchecker.get_tags(tags_now, i + this->nitems_read(m)); - for (unsigned int j = 0; j < tags_now.size(); j++) { - tag_t tag = tags_now[j]; - this->dispatch_msg(tag.key, tag.value); + // after the last tag, continue working on the remaining items + for (; in < reinterpret_cast<const IN_T*>(input_items[m]) + noutput_items; ++in) { + auto key = static_cast<unsigned int>(*in) * d_D; + for (unsigned int idx = 0; idx < d_D; ++idx) { + *out = d_symbol_table[key + idx]; + ++out; } - assert(((unsigned int)in[i] * d_D + d_D) <= d_symbol_table.size()); - memcpy(out, &d_symbol_table[(unsigned int)in[i] * d_D], d_D * sizeof(OUT_T)); - out += d_D; } } return noutput_items; |