diff options
4 files changed, 78 insertions, 10 deletions
diff --git a/gr-digital/include/digital/ofdm_frame_equalizer_vcvc.h b/gr-digital/include/digital/ofdm_frame_equalizer_vcvc.h index 21a976071d..23f3041e27 100644 --- a/gr-digital/include/digital/ofdm_frame_equalizer_vcvc.h +++ b/gr-digital/include/digital/ofdm_frame_equalizer_vcvc.h @@ -52,7 +52,8 @@ namespace gr { static sptr make( digital_ofdm_equalizer_base_sptr equalizer, const std::string &len_tag_key = "frame_len", - bool propagate_channel_state=false + bool propagate_channel_state=false, + int fixed_frame_len=0 ); }; diff --git a/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc b/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc index e9391658b6..168a04cf75 100644 --- a/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc +++ b/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc @@ -30,21 +30,39 @@ namespace gr { namespace digital { ofdm_frame_equalizer_vcvc::sptr - ofdm_frame_equalizer_vcvc::make(digital_ofdm_equalizer_base_sptr equalizer, const std::string &len_tag_key, bool propagate_channel_state) + ofdm_frame_equalizer_vcvc::make( + digital_ofdm_equalizer_base_sptr equalizer, + const std::string &len_tag_key, + bool propagate_channel_state, + int fixed_frame_len + ) { - return gnuradio::get_initial_sptr (new ofdm_frame_equalizer_vcvc_impl(equalizer, len_tag_key, propagate_channel_state)); + return gnuradio::get_initial_sptr ( + new ofdm_frame_equalizer_vcvc_impl( + equalizer, len_tag_key, propagate_channel_state, fixed_frame_len + ) + ); } - ofdm_frame_equalizer_vcvc_impl::ofdm_frame_equalizer_vcvc_impl(digital_ofdm_equalizer_base_sptr equalizer, const std::string &len_tag_key, bool propagate_channel_state) - : gr_tagged_stream_block("ofdm_frame_equalizer_vcvc", + ofdm_frame_equalizer_vcvc_impl::ofdm_frame_equalizer_vcvc_impl( + digital_ofdm_equalizer_base_sptr equalizer, + const std::string &len_tag_key, + bool propagate_channel_state, + int fixed_frame_len + ) : gr_tagged_stream_block("ofdm_frame_equalizer_vcvc", gr_make_io_signature(1, 1, sizeof (gr_complex) * equalizer->fft_len()), gr_make_io_signature(1, 1, sizeof (gr_complex) * equalizer->fft_len()), len_tag_key), d_fft_len(equalizer->fft_len()), d_eq(equalizer), d_propagate_channel_state(propagate_channel_state), + d_fixed_frame_len(len_tag_key.empty() ? fixed_frame_len : 0), d_channel_state(equalizer->fft_len(), gr_complex(1, 0)) - {} + { + if (d_fixed_frame_len) { + set_output_multiple(d_fixed_frame_len); + } + } ofdm_frame_equalizer_vcvc_impl::~ofdm_frame_equalizer_vcvc_impl() { @@ -60,6 +78,12 @@ namespace gr { const gr_complex *in = (const gr_complex *) input_items[0]; gr_complex *out = (gr_complex *) output_items[0]; int carrier_offset = 0; + int frame_len = 0; + if (d_fixed_frame_len) { + frame_len = d_fixed_frame_len; + } else { + frame_len = ninput_items[0]; + } std::vector<gr_tag_t> tags; get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+1); @@ -70,10 +94,10 @@ namespace gr { } } - memcpy((void *) out, (void *) in, sizeof(gr_complex) * d_fft_len * ninput_items[0]); + memcpy((void *) out, (void *) in, sizeof(gr_complex) * d_fft_len * frame_len); d_eq->reset(); d_eq->set_carrier_offset(carrier_offset); - d_eq->equalize(out, ninput_items[0], d_channel_state); + d_eq->equalize(out, frame_len, d_channel_state); d_eq->get_channel_state(d_channel_state); if (d_propagate_channel_state) { add_item_tag(0, nitems_written(0), @@ -81,7 +105,11 @@ namespace gr { pmt::pmt_init_c32vector(d_fft_len, d_channel_state)); } - return ninput_items[0]; + if (d_fixed_frame_len) { + consume_each(frame_len); + } + + return frame_len; } } /* namespace digital */ diff --git a/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.h b/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.h index ddfcc43694..89e59db053 100644 --- a/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.h +++ b/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.h @@ -33,6 +33,7 @@ namespace gr { const int d_fft_len; digital_ofdm_equalizer_base_sptr d_eq; bool d_propagate_channel_state; + const int d_fixed_frame_len; std::vector<gr_complex> d_channel_state; protected: @@ -41,7 +42,12 @@ namespace gr { void update_length_tags(int n_produced, int n_ports) {}; public: - ofdm_frame_equalizer_vcvc_impl(digital_ofdm_equalizer_base_sptr equalizer, const std::string &len_tag_key, bool propagate_channel_state); + ofdm_frame_equalizer_vcvc_impl( + digital_ofdm_equalizer_base_sptr equalizer, + const std::string &len_tag_key, + bool propagate_channel_state, + int fixed_frame_len + ); ~ofdm_frame_equalizer_vcvc_impl(); int work(int noutput_items, diff --git a/gr-digital/python/qa_ofdm_frame_equalizer_vcvc.py b/gr-digital/python/qa_ofdm_frame_equalizer_vcvc.py index 6f44fd00fb..cc369fafb5 100755 --- a/gr-digital/python/qa_ofdm_frame_equalizer_vcvc.py +++ b/gr-digital/python/qa_ofdm_frame_equalizer_vcvc.py @@ -106,6 +106,39 @@ class qa_ofdm_frame_equalizer_vcvc (gr_unittest.TestCase): if pmt.pmt_symbol_to_string(tag.key) == "ofdm_sync_chan_taps": self.assertEqual(list(pmt.pmt_c32vector_elements(tag.value)), channel[-fft_len:]) + def test_002_static_wo_tags (self): + fft_len = 8 + # 4 5 6 7 0 1 2 3 + tx_data = [-1, -1, 1, 2, -1, 3, 0, -1, # 0 + -1, -1, 0, 2, -1, 2, 0, -1, # 8 + -1, -1, 3, 0, -1, 1, 0, -1, # 16 (Pilot symbols) + -1, -1, 1, 1, -1, 0, 2, -1] # 24 + cnst = digital.constellation_qpsk() + tx_signal = [cnst.map_to_points_v(x)[0] if x != -1 else 0 for x in tx_data] + occupied_carriers = ((1, 2, 6, 7),) + pilot_carriers = ((), (), (1, 2, 6, 7), ()) + pilot_symbols = ( + [], [], [cnst.map_to_points_v(x)[0] for x in (1, 0, 3, 0)], [] + ) + equalizer = digital.ofdm_equalizer_static(fft_len, occupied_carriers, pilot_carriers, pilot_symbols) + channel = [ + 0, 0, 1, 1, 0, 1, 1, 0, + 0, 0, 1, 1, 0, 1, 1, 0, # These coefficients will be rotated slightly... + 0, 0, 1j, 1j, 0, 1j, 1j, 0, # Go crazy here! + 0, 0, 1j, 1j, 0, 1j, 1j, 0 # ...and again here. + ] + for idx in range(fft_len, 2*fft_len): + channel[idx] = channel[idx-fft_len] * numpy.exp(1j * .1 * numpy.pi * (numpy.random.rand()-.5)) + idx2 = idx+2*fft_len + channel[idx2] = channel[idx2] * numpy.exp(1j * 0 * numpy.pi * (numpy.random.rand()-.5)) + src = gr.vector_source_c(numpy.multiply(tx_signal, channel), False, fft_len) + eq = digital.ofdm_frame_equalizer_vcvc(equalizer.base(), "", False, 4) + sink = gr.vector_sink_c(fft_len) + self.tb.connect(src, eq, sink) + self.tb.run () + rx_data = [cnst.decision_maker_v((x,)) if x != 0 else -1 for x in sink.data()] + self.assertEqual(tx_data, rx_data) + def test_002_simpledfe (self): fft_len = 8 # 4 5 6 7 0 1 2 3 |