diff options
author | Martin Braun <martin.braun@ettus.com> | 2014-09-19 16:35:43 -0400 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2014-09-21 15:42:53 -0400 |
commit | 796cc152530bce73bc07a8628e7e6502794bf900 (patch) | |
tree | 3f879a04f9acdc9b454cb1163668d4139629af6b | |
parent | 6e1207475b6942a341466cc367e77eb79dae931e (diff) |
digital: Removed all references to remove_item_tag()
6 files changed, 207 insertions, 109 deletions
diff --git a/gr-digital/include/gnuradio/digital/ofdm_frame_equalizer_vcvc.h b/gr-digital/include/gnuradio/digital/ofdm_frame_equalizer_vcvc.h index 2715316a93..be38b6f8ae 100644 --- a/gr-digital/include/gnuradio/digital/ofdm_frame_equalizer_vcvc.h +++ b/gr-digital/include/gnuradio/digital/ofdm_frame_equalizer_vcvc.h @@ -58,18 +58,19 @@ namespace gr { /*! * \param equalizer The equalizer object that will do the actual work * \param cp_len Length of the cyclic prefix in samples (required to correct the frequency offset) - * \param len_tag_key Length tag key + * \param tsb_key TSB key * \param propagate_channel_state If true, the channel state after the last symbol * will be added to the first symbol as a tag - * \param fixed_frame_len Set if the frame length is fixed throughout, - * helps with book keeping. + * \param fixed_frame_len Set if the frame length is fixed. When this value is given, + * the TSB tag key can be left empty, but it is useful even + * when using tagged streams at the input. */ static sptr make( - ofdm_equalizer_base::sptr equalizer, - int cp_len, - const std::string &len_tag_key = "frame_len", - bool propagate_channel_state=false, - int fixed_frame_len=0 + ofdm_equalizer_base::sptr equalizer, + int cp_len, + const std::string &tsb_key="frame_len", + bool propagate_channel_state=false, + int fixed_frame_len=0 ); }; diff --git a/gr-digital/lib/header_payload_demux_impl.cc b/gr-digital/lib/header_payload_demux_impl.cc index 15308c0be1..160f54036d 100644 --- a/gr-digital/lib/header_payload_demux_impl.cc +++ b/gr-digital/lib/header_payload_demux_impl.cc @@ -1,5 +1,5 @@ /* -*- c++ -*- */ -/* Copyright 2012,2013 Free Software Foundation, Inc. +/* Copyright 2012-2014 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -300,20 +300,19 @@ namespace gr { } } if (d_uses_trigger_tag) { - std::vector<tag_t> tags; - get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+noutput_items, d_trigger_tag_key); - uint64_t min_offset = ULLONG_MAX; - int tag_index = -1; - for (unsigned i = 0; i < tags.size(); i++) { - if (tags[i].offset < min_offset) { - tag_index = (int) i; - min_offset = tags[i].offset; - } - } - if (tag_index != -1) { - remove_item_tag(0, tags[tag_index]); - return min_offset - nitems_read(0); - } + std::vector<tag_t> tags; + get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+noutput_items, d_trigger_tag_key); + uint64_t min_offset = ULLONG_MAX; + int tag_index = -1; + for (unsigned i = 0; i < tags.size(); i++) { + if (tags[i].offset < min_offset) { + tag_index = (int) i; + min_offset = tags[i].offset; + } + } + if (tag_index != -1) { + return min_offset - nitems_read(0); + } } return -1; } /* find_trigger_signal() */ @@ -388,26 +387,30 @@ namespace gr { // Copy tags std::vector<tag_t> tags; get_tags_in_range( - tags, 0, - nitems_read(0), - nitems_read(0) + n_symbols * (d_items_per_symbol + d_gi) + tags, 0, + nitems_read(0), + nitems_read(0) + n_symbols * (d_items_per_symbol + d_gi) ); - for (unsigned t = 0; t < tags.size(); t++) { - int new_offset = tags[t].offset - nitems_read(0); - if (d_output_symbols) { - new_offset /= (d_items_per_symbol + d_gi); - } else if (d_gi) { - int pos_on_symbol = (new_offset % (d_items_per_symbol + d_gi)) - d_gi; - if (pos_on_symbol < 0) { - pos_on_symbol = 0; - } - new_offset = (new_offset / (d_items_per_symbol + d_gi)) + pos_on_symbol; - } - add_item_tag(port, - nitems_written(port) + new_offset, - tags[t].key, - tags[t].value - ); + for (size_t t = 0; t < tags.size(); t++) { + // The trigger tag is *not* propagated + if (tags[t].key == d_trigger_tag_key) { + continue; + } + int new_offset = tags[t].offset - nitems_read(0); + if (d_output_symbols) { + new_offset /= (d_items_per_symbol + d_gi); + } else if (d_gi) { + int pos_on_symbol = (new_offset % (d_items_per_symbol + d_gi)) - d_gi; + if (pos_on_symbol < 0) { + pos_on_symbol = 0; + } + new_offset = (new_offset / (d_items_per_symbol + d_gi)) + pos_on_symbol; + } + add_item_tag(port, + nitems_written(port) + new_offset, + tags[t].key, + tags[t].value + ); } } /* copy_n_symbols() */ diff --git a/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc b/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc index 4446306a8b..70e840d778 100644 --- a/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc +++ b/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc @@ -29,6 +29,9 @@ #define M_TWOPI (2*M_PI) +static const pmt::pmt_t CARR_OFFSET_KEY = pmt::mp("ofdm_sync_carr_offset"); +static const pmt::pmt_t CHAN_TAPS_KEY = pmt::mp("ofdm_sync_chan_taps"); + namespace gr { namespace digital { @@ -36,14 +39,14 @@ namespace gr { ofdm_frame_equalizer_vcvc::make( ofdm_equalizer_base::sptr equalizer, int cp_len, - const std::string &len_tag_key, + const std::string &tsb_key, bool propagate_channel_state, int fixed_frame_len ) { return gnuradio::get_initial_sptr ( new ofdm_frame_equalizer_vcvc_impl( - equalizer, cp_len, len_tag_key, propagate_channel_state, fixed_frame_len + equalizer, cp_len, tsb_key, propagate_channel_state, fixed_frame_len ) ); } @@ -51,13 +54,13 @@ namespace gr { ofdm_frame_equalizer_vcvc_impl::ofdm_frame_equalizer_vcvc_impl( ofdm_equalizer_base::sptr equalizer, int cp_len, - const std::string &len_tag_key, + const std::string &tsb_key, bool propagate_channel_state, int fixed_frame_len ) : tagged_stream_block("ofdm_frame_equalizer_vcvc", io_signature::make(1, 1, sizeof (gr_complex) * equalizer->fft_len()), io_signature::make(1, 1, sizeof (gr_complex) * equalizer->fft_len()), - len_tag_key), + tsb_key), d_fft_len(equalizer->fft_len()), d_cp_len(cp_len), d_eq(equalizer), @@ -65,16 +68,18 @@ namespace gr { d_fixed_frame_len(fixed_frame_len), d_channel_state(equalizer->fft_len(), gr_complex(1, 0)) { - if (len_tag_key.empty() && fixed_frame_len == 0) { - throw std::invalid_argument("Either specify a length tag or a frame length!"); + if (tsb_key.empty() && fixed_frame_len == 0) { + throw std::invalid_argument("Either specify a TSB tag or a fixed frame length!"); } if (d_fixed_frame_len < 0) { - throw std::invalid_argument("Invalid frame length!"); + throw std::invalid_argument("Invalid frame length!"); } if (d_fixed_frame_len) { - set_output_multiple(d_fixed_frame_len); + set_output_multiple(d_fixed_frame_len); } set_relative_rate(1.0); + // Really, we have TPP_ONE_TO_ONE, but the channel state is not propagated + set_tag_propagation_policy(TPP_DONT); } ofdm_frame_equalizer_vcvc_impl::~ofdm_frame_equalizer_vcvc_impl() @@ -83,18 +88,17 @@ namespace gr { void ofdm_frame_equalizer_vcvc_impl::parse_length_tags( - const std::vector<std::vector<tag_t> > &tags, - gr_vector_int &n_input_items_reqd - ){ + const std::vector<std::vector<tag_t> > &tags, + gr_vector_int &n_input_items_reqd + ) { if (d_fixed_frame_len) { - n_input_items_reqd[0] = d_fixed_frame_len; + n_input_items_reqd[0] = d_fixed_frame_len; } else { - for (unsigned k = 0; k < tags[0].size(); k++) { - if (tags[0][k].key == pmt::string_to_symbol(d_length_tag_key_str)) { - n_input_items_reqd[0] = pmt::to_long(tags[0][k].value); - remove_item_tag(0, tags[0][k]); - } - } + for (unsigned k = 0; k < tags[0].size(); k++) { + if (tags[0][k].key == pmt::string_to_symbol(d_length_tag_key_str)) { + n_input_items_reqd[0] = pmt::to_long(tags[0][k].value); + } + } } } @@ -114,15 +118,14 @@ namespace gr { } std::vector<tag_t> tags; - get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+1); + get_tags_in_window(tags, 0, 0, 1); for (unsigned i = 0; i < tags.size(); i++) { - if (pmt::symbol_to_string(tags[i].key) == "ofdm_sync_chan_taps") { - d_channel_state = pmt::c32vector_elements(tags[i].value); - remove_item_tag(0, tags[i]); - } - if (pmt::symbol_to_string(tags[i].key) == "ofdm_sync_carr_offset") { - carrier_offset = pmt::to_long(tags[i].value); - } + if (pmt::symbol_to_string(tags[i].key) == "ofdm_sync_chan_taps") { + d_channel_state = pmt::c32vector_elements(tags[i].value); + } + if (pmt::symbol_to_string(tags[i].key) == "ofdm_sync_carr_offset") { + carrier_offset = pmt::to_long(tags[i].value); + } } // Copy the frame and the channel state vector such that the symbols are shifted to the correct position @@ -157,7 +160,16 @@ namespace gr { // Update the channel state regarding the frequency offset phase_correction = gr_expj(M_TWOPI * carrier_offset * d_cp_len / d_fft_len * frame_len); for (int k = 0; k < d_fft_len; k++) { - d_channel_state[k] *= phase_correction; + d_channel_state[k] *= phase_correction; + } + + // Propagate tags (except for the channel state and the TSB tag) + get_tags_in_window(tags, 0, 0, frame_len); + for (size_t i = 0; i < tags.size(); i++) { + if (tags[i].key != CHAN_TAPS_KEY + and tags[i].key != pmt::mp(d_length_tag_key_str)) { + add_item_tag(0, tags[i]); + } } // Housekeeping diff --git a/gr-digital/lib/ofdm_serializer_vcc_impl.cc b/gr-digital/lib/ofdm_serializer_vcc_impl.cc index f6c796d3c5..1398dcd2a1 100644 --- a/gr-digital/lib/ofdm_serializer_vcc_impl.cc +++ b/gr-digital/lib/ofdm_serializer_vcc_impl.cc @@ -1,5 +1,5 @@ /* -*- c++ -*- */ -/* Copyright 2012 Free Software Foundation, Inc. +/* Copyright 2012,2014 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -157,55 +157,57 @@ namespace gr { std::vector<tag_t> tags; // Packet mode if (!d_length_tag_key_str.empty()) { - get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+1); - for (unsigned i = 0; i < tags.size(); i++) { - if (tags[i].key == d_carr_offset_key) { - carr_offset = pmt::to_long(tags[i].value); - } - if (tags[i].key == d_packet_len_tag_key) { - packet_length = pmt::to_long(tags[i].value); - remove_item_tag(0, tags[i]); - } - } + get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+1); + for (unsigned i = 0; i < tags.size(); i++) { + if (tags[i].key == d_carr_offset_key) { + carr_offset = pmt::to_long(tags[i].value); + } + if (tags[i].key == d_packet_len_tag_key) { + packet_length = pmt::to_long(tags[i].value); + } + } } else { - // recalc frame length from noutput_items - frame_length = 0; - int sym_per_frame = 0; - while ((sym_per_frame + d_occupied_carriers[(frame_length + 1) % d_occupied_carriers.size()].size()) < (size_t)noutput_items) { - frame_length++; - sym_per_frame += d_occupied_carriers[(frame_length + 1) % d_occupied_carriers.size()].size(); - } + // recalc frame length from noutput_items + frame_length = 0; + int sym_per_frame = 0; + while ((sym_per_frame + d_occupied_carriers[(frame_length + 1) % d_occupied_carriers.size()].size()) < (size_t)noutput_items) { + frame_length++; + sym_per_frame += d_occupied_carriers[(frame_length + 1) % d_occupied_carriers.size()].size(); + } } // Copy symbols int n_out_symbols = 0; for (int i = 0; i < frame_length; i++) { - // Copy all tags associated with this input OFDM symbol onto the first output symbol - get_tags_in_range(tags, 0, - nitems_read(0)+i, - nitems_read(0)+i+1 - ); - for (unsigned t = 0; t < tags.size(); t++) { - add_item_tag(0, nitems_written(0)+n_out_symbols, - tags[t].key, - tags[t].value - ); - } - for (unsigned k = 0; k < d_occupied_carriers[d_curr_set].size(); k++) { - out[n_out_symbols++] = in[i * d_fft_len + d_occupied_carriers[d_curr_set][k] + carr_offset]; - } - if (packet_length && n_out_symbols > packet_length) { - n_out_symbols = packet_length; - break; - } - d_curr_set = (d_curr_set + 1) % d_occupied_carriers.size(); + // Copy all tags associated with this input OFDM symbol onto the first output symbol + get_tags_in_range(tags, 0, + nitems_read(0)+i, + nitems_read(0)+i+1 + ); + for (size_t t = 0; t < tags.size(); t++) { + // The packet length tag is not propagated + if (tags[t].key != d_packet_len_tag_key) { + add_item_tag(0, nitems_written(0)+n_out_symbols, + tags[t].key, + tags[t].value + ); + } + } + for (unsigned k = 0; k < d_occupied_carriers[d_curr_set].size(); k++) { + out[n_out_symbols++] = in[i * d_fft_len + d_occupied_carriers[d_curr_set][k] + carr_offset]; + } + if (packet_length && n_out_symbols > packet_length) { + n_out_symbols = packet_length; + break; + } + d_curr_set = (d_curr_set + 1) % d_occupied_carriers.size(); } // Housekeeping if (d_length_tag_key_str.empty()) { - consume_each(frame_length); + consume_each(frame_length); } else { - d_curr_set = d_symbols_skipped; + d_curr_set = d_symbols_skipped; } return n_out_symbols; diff --git a/gr-digital/python/digital/qa_header_payload_demux.py b/gr-digital/python/digital/qa_header_payload_demux.py index 0b754fe248..8006d4442e 100755 --- a/gr-digital/python/digital/qa_header_payload_demux.py +++ b/gr-digital/python/digital/qa_header_payload_demux.py @@ -113,6 +113,86 @@ class qa_header_payload_demux (gr_unittest.TestCase): ] self.assertEqual(expected_tags_payload, ptags_payload) + def test_001_t_tags (self): + """ Like the previous test, but use a trigger tag instead of + a trigger signal. + """ + n_zeros = 1 + header = (1, 2, 3) + payload = tuple(range(5, 20)) + data_signal = (0,) * n_zeros + header + payload + # Trigger tag + trigger_tag = gr.tag_t() + trigger_tag.offset = n_zeros + trigger_tag.key = pmt.string_to_symbol('detect') + trigger_tag.value = pmt.PMT_T + # This is dropped: + testtag1 = gr.tag_t() + testtag1.offset = 0 + testtag1.key = pmt.string_to_symbol('tag1') + testtag1.value = pmt.from_long(0) + # This goes on output 0, item 0: + testtag2 = gr.tag_t() + testtag2.offset = n_zeros + testtag2.key = pmt.string_to_symbol('tag2') + testtag2.value = pmt.from_long(23) + # This goes on output 0, item 2: + testtag3 = gr.tag_t() + testtag3.offset = n_zeros + len(header) - 1 + testtag3.key = pmt.string_to_symbol('tag3') + testtag3.value = pmt.from_long(42) + # This goes on output 1, item 3: + testtag4 = gr.tag_t() + testtag4.offset = n_zeros + len(header) + 3 + testtag4.key = pmt.string_to_symbol('tag4') + testtag4.value = pmt.from_long(314) + data_src = blocks.vector_source_f( + data_signal, + False, + tags=(trigger_tag, testtag1, testtag2, testtag3, testtag4) + ) + hpd = digital.header_payload_demux( + len(header), 1, 0, "frame_len", "detect", False, gr.sizeof_float + ) + self.assertEqual(pmt.length(hpd.message_ports_in()), 2) #extra system port defined for you + header_sink = blocks.vector_sink_f() + payload_sink = blocks.vector_sink_f() + + self.tb.connect(data_src, (hpd, 0)) + self.tb.connect((hpd, 0), header_sink) + self.tb.connect((hpd, 1), payload_sink) + self.tb.start() + time.sleep(.2) # Need this, otherwise, the next message is ignored + hpd.to_basic_block()._post( + pmt.intern('header_data'), + pmt.from_long(len(payload)) + ) + while len(payload_sink.data()) < len(payload): + time.sleep(.2) + self.tb.stop() + self.tb.wait() + + self.assertEqual(header_sink.data(), header) + self.assertEqual(payload_sink.data(), payload) + ptags_header = [] + for tag in header_sink.tags(): + ptag = gr.tag_to_python(tag) + ptags_header.append({'key': ptag.key, 'offset': ptag.offset}) + expected_tags_header = [ + {'key': 'tag2', 'offset': 0}, + {'key': 'tag3', 'offset': 2}, + ] + self.assertEqual(expected_tags_header, ptags_header) + ptags_payload = [] + for tag in payload_sink.tags(): + ptag = gr.tag_to_python(tag) + ptags_payload.append({'key': ptag.key, 'offset': ptag.offset}) + expected_tags_payload = [ + {'key': 'frame_len', 'offset': 0}, + {'key': 'tag4', 'offset': 3}, + ] + self.assertEqual(expected_tags_payload, ptags_payload) + def test_002_symbols (self): """ Same as before, but operate on symbols diff --git a/gr-digital/python/digital/qa_ofdm_frame_equalizer_vcvc.py b/gr-digital/python/digital/qa_ofdm_frame_equalizer_vcvc.py index c42fb2b907..1b3ffb7738 100755 --- a/gr-digital/python/digital/qa_ofdm_frame_equalizer_vcvc.py +++ b/gr-digital/python/digital/qa_ofdm_frame_equalizer_vcvc.py @@ -72,7 +72,7 @@ class qa_ofdm_frame_equalizer_vcvc (gr_unittest.TestCase): ptag = gr.tag_to_python(tag) tag_dict[ptag.key] = ptag.value expected_dict = { - 'foo': 42 + 'foo': 42 } self.assertEqual(tag_dict, expected_dict) |